以下の内容は 2026 年 10 月 23 日時点の Firebase のドキュメントに基づいています。最新の上限はそちらで確認してください。Firebase が何を送信し、どうテストするかといった基本については、Firebase Authentication のメールをテストする から始めてください。
メールが届かない
誰も送信を要求していません。 createUserWithEmailAndPassword はアカウントを作成しますが、メールは送信しません。サインアップのコードで、新しいユーザーに対して sendEmailVerification を呼び出す必要があります。呼び出さないと、アカウントは未確認のままになり、テスターは届かないメールを待ち続けることになります。
そのアドレスにアカウントがありません。 メール列挙保護(2023 年 9 月 15 日以降に作成されたプロジェクトではデフォルトで有効)が有効な場合、sendPasswordResetEmail はアドレスがアカウントに属するときだけ送信し、属さないときもエラーを返しません。一度もサインアップしていないアドレスでリセットをテストすると、アプリでは成功しても何も届きません。先にサインアップしてから、リセットしてください。
1 日の上限に達しました。 無料の Spark プランでは、Firebase が 1 日に送信できるのは、メールリンクによるサインイン 5 通、パスワードリセット 150 通、確認メール 1,000 通です。パスワードレスサインインは、その日 5 回目のテストの後に止まります。ステージングでは課金(Blaze)を追加するか、メールリンクによるサインインのテストは控えめにしてください。
迷惑メールに入っています。 デフォルトでは、メールはプロジェクトの firebaseapp.com アドレス noreply@ から送信され、一部の受信トレイはこれを信頼しません。コンソールのメールテンプレートで独自ドメインを設定してください。Proxy Mail QA のアドレスならどちらの場合も受信できるので、「送信されていない」のか「迷惑メールに送られた」のかを見分けられます。
エミュレーターを使っています。 Auth エミュレーターはメールを送信しません。確認、リセット、サインインの各リンクを、実行中のターミナルと Emulator Suite の Logs タブに出力し、テスト用に REST エンドポイントでも提供します。リリース前には実際のステージングプロジェクトでテストしてください。
サインアップに失敗する
auth/email-already-in-use: そのアドレスにはすでにアカウントがあります。列挙保護でもこのエラーは隠されません。実行のたびに新しいアドレスを使ってください。- サインアップが多すぎます: Firebase では、1 つの IP アドレスから 1 時間に作成できる新規アカウントは 100 件までです。1 台の CI マシンから実行するテストスイートでは、これを超えることがあります。Firebase コンソールで一時的な引き上げを予約できます。
- パスワードのルール: パスワードポリシーを有効にしている場合、弱いパスワードは
auth/password-does-not-meet-requirementsで失敗します。フォームで理由を表示するようにしてください。 - ボット対策: Authentication の reCAPTCHA 保護や App Check の適用により、自動化されたブラウザが拒否されることがあります。App Check については、テスト実行にデバッグトークンを渡してください。
サインインが auth/invalid-credential で失敗する
列挙保護が有効な場合、パスワードの誤りと不明なアドレスは同じエラー(INVALID_LOGIN_CREDENTIALS。Web SDK では auth/invalid-credential として報告されます)になります。auth/user-not-found や auth/wrong-password を期待するテストは失敗するようになり、それぞれに別のメッセージを表示するアプリも同様です。代わりに、単一のエラーを確認してください。
リンクはクリックされたのに、アプリにまだ「メールを確認してください」と表示される
アプリが保持する User オブジェクトは、サインイン時の emailVerified の値を保持したままです。別のタブでリンクがクリックされた後に user.reload() を呼び出し、セキュリティルールやバックエンドが email_verified クレームを読み取る場合は user.getIdToken(true) も呼び出してください。それまでは、アプリもルールも未確認のユーザーとして扱います。
リンクが失敗する
auth/invalid-action-codeまたはauth/expired-action-code: リンクはすでに使用済みか、期限切れです。新しいメールを要求し、最新のものを使ってください。auth/unauthorized-continue-uri: コードが渡す続行 URL が承認済みドメインにありません。Authentication の Settings にある Authorized domains に各環境を追加してください。プレビューデプロイには新しいドメインが割り当てられるため、それぞれ追加するか、固定のステージングドメインを使ってください。- localhost に飛ぶ: 続行 URL はコードから来ています。ハードコードした
http://localhostではなく、環境設定から組み立ててください。詳しくは メールのリンクが localhost を指す理由 をご覧ください。
メールリンクによるサインインで、メールアドレスを再度求められる
メールリンクによるサインインは、リンクを要求したブラウザで完了します。アプリはアドレスをそのブラウザ(通常は localStorage)に保存し、リンクが開かれたときに読み戻します。別のデバイスやブラウザでリンクを開いた場合、セッション固定攻撃を防ぐためにアドレスを再度求めるよう Firebase 自身が推奨しています。これは想定どおりの動作です。テスターは開始したのと同じ場所でリンクを開いてください。モバイルアプリでは、リンクでアプリも開く必要があり、Dynamic Links の終了後は仕組みが異なります。モバイルアプリでの Firebase メールリンクによるサインイン をご覧ください。
一度にすべて確認する
- シナリオごとに新しい Proxy Mail QA アドレスを作成します:新規ユーザー、パスワードリセット(サインアップ済みのアドレスで)、メールリンクによるサインイン。
- アプリでフローを進めます。リンクは数秒以内にそのアドレスの行に表示されます。表示されなければ、何も送信されていないということです。
- 行を確認します。localhost へのリンクには警告が付き、受信トレイには各メールの送信者とチェック結果が表示されます。
checkEmailとexpectHostを使えば、リンクの行き先が自分のサイト以外ならテストを失敗にできます。 - 同じブラウザでリンクを開き、サインアウトして再度サインインしなくても、アプリでユーザーが確認済みと表示されることを確認します。
Antigravity や他の AI ツールで作りましたか?生成されたアプリがこれらに加えてよく間違える点は、バイブコーディングで作ったサインアップとログインの問題 で説明しています。