当サイトは、一部記事に広告を含みます

【Next.js × Firebase】開発環境だけメール認証が auth/invalid-action-codeで失敗する原因と対処法

Next.js(React)で Firebase のメール認証を実装していたとき、開発環境でのみ
「認証コードが無効です(auth/invalid-action-code)」 が発生しました。

  • 本番環境 → 問題なし
  • 開発環境(next dev) → 失敗

しかも oobCode(認証コード)は正しい はずなのに、なぜか失敗する。

発生した問題|メール認証が開発環境でのみ失敗する

※メール認証リンクが届くまでのフローは割愛

  1. ユーザーがメール認証リンクをクリック
  2. oobCode(認証コード)付きの URL でアプリに戻る
  3. applyActionCode() を実行 → 一瞬成功
  4. 直後に FirebaseError: Firebase: Error (auth/invalid-action-code) が発生して失敗扱いになる。oobCodeは正しいっぽい。

実際のコード

useEffect(() => {
  const queryParams = new URLSearchParams(window.location.search)
  const oobCode = queryParams.get('oobCode');

  if (!oobCode) {
    setError("認証コードが見つかりません。");
    return;
  }

  const auth = getAuth();
  applyActionCode(auth, oobCode)
    .then(() => {
      setIsSuccess(true);
      setError(null);
    })
    .catch((e) => {
      setError(`認証に失敗した可能性があります。<br />フォームよりお問い合わせください。`);
      console.error("Error applying action code:", e);
      setIsSuccess(false);
    })
}, []);

原因|Strict Modeによるコンポーネントの二重レンダリング

Next.js の開発環境では reactStrictMode がデフォルトで有効になっており、同じコンポーネントを意図的に2回レンダリング します。

(参考)StrictModeとは:https://ja.react.dev/reference/react/StrictMode

メール認証のフローでは、これが次のような問題を引き起こしていたもよう🤔

1回目のレンダリング:

  • useEffect が走り applyActionCode() 実行
  • コードが正常に処理され「使用済み」状態になる

2回目のレンダリング:

  • 再び useEffect が走り applyActionCode() 実行
  • 既に使われたコードなので auth/invalid-action-code が返る

結果としてユーザーには「失敗」画面が出てしまいます。
(本番環境は reactStrictMode 無効なのでこの挙動は発生しない)

調査|reactStrictModeを一時的に無効にする

本当にreactStrictModeが原因なのか?確認するなら、reactStrictModeを一時的に無効にしてみるのが手っ取り早かった。

next.config.jsファイルを編集し、reactStrictModeを一時的に無効にすることで、開発環境での二重レンダリングを停止させます。

// next.config.js

サーバーを再起動すれば、開発環境でもメール認証が通るように🎉 = StrictModeが原因!

対応|useRefでuseEffectの初回実行を制御する

reactStrictMode は潜在的なバグを検出するための重要な機能なので、恒久的に OFF にするのは非推奨。ということで、対応としてuseRef などで useEffect の初回実行を制御する実装に修正します。

const isInitialMount = useRef(true);

useEffect(() => {
    // 開発環境のStrictModeによる二重実行を回避
    if (!isInitialMount.current) return;
    isInitialMount.current = false;

}, []);

まとめ|Next.js × Firebaseで開発環境だけメール認証がauth/invalid-action-codeエラーになる原因はStrict Modeだった

開発環境のみレンダリングが2度走っていることは知っていましたが、それが今回のメール認証エラーの原因だと気がつくまでちょっと時間がかかりました・・・!

Strict Modeをオフにするだけで手っ取り早く解決したいところだったのですが、根本の解決には至っていないということで、useRefを使ってuseEffectの初回実行を制御することとしました。

---

記事が気に入ったら、ぜひ応援いただけると更新がんばれます☕️

Buy Me A Coffee