Android で Firebase の電話番号の確認エラーを処理する

Firebase PNV ライブラリの呼び出しが失敗すると、ライブラリは FirebasePhoneNumberVerificationException を報告します。このページでは、例外が返す可能性のあるすべてのエラーコード、各エラーコードが発生するタイミング、アプリがそれに対して行うべき処理について説明します。

このページでは、Android で Firebase Phone Number Verification を使ってみるの説明に沿って Firebase PNV を統合していることを前提としています。

エラーの報告方法

  • 非同期メソッド(getVerificationSupportInfo()、getVerifiedPhoneNumber()、カスタムフロー メソッド)は Task を返します。失敗すると、Task は FirebasePhoneNumberVerificationException で失敗し、addOnFailureListener で受信されます。

  • enableTestSession() は同期です。FirebasePhoneNumberVerificationException を直接スローします。

例外の errorCode を読み、何が問題だったかを確認します。Firebase PNV コードは、FirebasePnvStatusCodes クラスの定数です。Google Play 開発者サービスでエラーが発生した場合、errorCode は NETWORK_ERROR などの CommonStatusCodes 値になることもあります。

サポートされていないデバイスまたは SIM はエラーではありません。getVerificationSupportInfo() が成功し、その SIM の isSupported() が false として報告され、getReason() でその理由が示されます。サポートされていないデバイスと SIM を参照してください。

エラーコード

テスト セッションのセットアップ

これらのエラーは、enableTestSession() によって同期的にスローされます。

エラーコード 原因 推奨される対処方法
TEST_SESSION_ALREADY_ENABLED
(55508)
enableTestSession() が同じアプリプロセスで複数回呼び出されました。FirebasePhoneNumberVerification.getInstance() は毎回同じインスタンスを返すため、これを呼び出す Activity が再作成された場合にも、この処理が行われます。 enableTestSession() は、プロセスごとに 1 回呼び出します(Application.onCreate() など)。テストモードでライブラリを初期化するをご覧ください。
INVALID_TEST_NUMBER_ID
(55507)
enableTestSession() に渡されたテストトークンが空です。 Firebase コンソールで生成したトークンがビルドに渡されるようにし、トークンが空でない場合にのみ enableTestSession() を呼び出します。

検証

これらのエラーが発生すると、getVerifiedPhoneNumber() によって返される Task が失敗します。

エラーコード 原因 推奨される対処方法
CREDENTIAL_MANAGER_ERROR
(55506)
Android 認証情報マネージャーが電話番号を返しませんでした。例外の cause が GetCredentialCancellationException の場合、ユーザーが同意画面を閉じた可能性があります。 SMS など、電話番号を確認する別の方法を提供します。ユーザーに同意画面が再度表示されるため、自動的に再試行しないでください。
CARRIER_NOT_SUPPORTED
(55501)
選択した SIM の携帯通信会社がサポートされていないか、デバイスに検証に必要なサブスクリプション情報がありません。 SMS などの別の確認方法にフォールバックする。
UNSUPPORTED_OPERATION
(55505)
Firebase PNV は、デバイスでのこのリクエストには使用できません。 SMS などの別の確認方法にフォールバックする。
PREFLIGHT_CHECK_FAILED
(55504)
同意画面が表示される前に、Firebase PNV バックエンドで確認リクエストを作成できませんでした。 SMS などの別の確認方法にフォールバックします。すべてのリクエストで発生する場合は、アプリが正しく設定されていることを確認します(本番環境モードにアップグレードするをご覧ください)。
INTEGRITY_CHECK_FAILED
(55503)
デバイスまたはアプリが完全性チェックに合格しなかった。 SMS などの別の確認方法にフォールバックする。
INVALID_DIGITAL_CREDENTIAL_RESPONSE
(55502)
認証情報マネージャーからのレスポンスを読み取れなかったか、確認済みの電話番号と交換できませんでした。 SMS などの別の確認方法にフォールバックする。
INVALID_TEST_NUMBER_ID
(55507)
テストモードで、Firebase PNV バックエンドがテストトークンを拒否しました(有効期限が切れているなど)。テストトークンの TTL は 7 日間です。通常、拒否されたテストトークンはこのコードを報告します。テストモードで他のエラーが表示された場合は、トークンが最新であることも確認してください。 Firebase コンソールで新しいテストトークンを生成し、アプリを再ビルドします。
ACTIVITY_CONTEXT_REQUIRED
(55509)
getVerifiedPhoneNumber() に渡された Context が Activity ではありません。このメソッドでは、同意画面を表示するために Activity が必要です。 現在の Activity を渡します。これはアプリのバグであり、実行時に処理する条件ではありません。

サポート チェック

getVerificationSupportInfo() によって返される Task は、チェック自体を実行できない場合にのみ失敗します。この場合、errorCode は Google Play 開発者サービスの CommonStatusCodes 値または CARRIER_NOT_SUPPORTED です。デバイスをサポート対象外として扱い、SMS などの別の確認方法にフォールバックします。

テスト セッションが有効になっている間、getVerificationSupportInfo() は Firebase PNV バックエンドに接続せず、テストトークンの有効期限が切れている場合でも、テスト SIM を常にサポート対象として報告します。

カスタムフロー

getVerifiedPhoneNumber() ではなくカスタムフローを使用する場合:

  • getDigitalCredentialPayload() は PREFLIGHT_CHECK_FAILED で失敗します。バックエンドがテストトークンを拒否した場合は INVALID_TEST_NUMBER_ID で失敗します。
  • exchangeCredentialResponseForPhoneNumber() が INVALID_DIGITAL_CREDENTIAL_RESPONSE で失敗するか、バックエンドがテストトークンを拒否した場合は INVALID_TEST_NUMBER_ID で失敗します。
  • 認証情報マネージャーへの独自の呼び出しで GetCredentialException がスローされ、直接処理されます。

サポートされていないデバイスと SIM

SIM の isSupported() が false の場合、getReason() は次の VerificationSupportStatus 値のいずれかを返します。

値 意味
INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED SIM の携帯通信会社がサポートされていません。サポートされている携帯通信会社をご覧ください。
INCAPABLE_DUE_TO_ANDROID_VERSION デバイスで Android 9(API レベル 28)より前のバージョンの Android が実行されている。
INCAPABLE_DUE_TO_SIM_STATE SIM の準備ができていません。ロックされている SIM や読み込み中の SIM でも、携帯通信会社が最初に確認されるため、INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED が報告されることがあります。

いずれの場合も、その SIM には SMS などの別の確認方法を使用してください。

例

次の例では、getVerifiedPhoneNumber() を呼び出すときに一般的なアプリが区別する必要があるエラーを処理しています。

Kotlin

import android.util.Log
// Credential Manager is included with the Firebase PNV library.
import androidx.credentials.exceptions.GetCredentialCancellationException
import com.google.firebase.pnv.FirebasePhoneNumberVerification
import com.google.firebase.pnv.FirebasePhoneNumberVerificationException
import com.google.firebase.pnv.FirebasePnvStatusCodes

private const val TAG = "PhoneVerification"

// In your Activity:
private fun verifyPhoneNumber() {
    FirebasePhoneNumberVerification.getInstance()
        .getVerifiedPhoneNumber(this)
        .addOnSuccessListener { result ->
            // Send result.getToken() to your backend.
        }
        .addOnFailureListener { e -> handleFpnvError(e) }
}

private fun handleFpnvError(e: Exception) {
    if (e !is FirebasePhoneNumberVerificationException) {
        Log.w(TAG, "Firebase PNV failed", e)
        showSmsVerification()
        return
    }
    when (e.errorCode) {
        FirebasePnvStatusCodes.CREDENTIAL_MANAGER_ERROR -> {
            if (e.cause is GetCredentialCancellationException) {
                // The user dismissed the consent screen.
            }
            showSmsVerification()
        }
        FirebasePnvStatusCodes.INVALID_TEST_NUMBER_ID -> {
            // Test mode only: generate a new test token.
            Log.e(TAG, "Firebase PNV test token rejected", e)
        }
        FirebasePnvStatusCodes.ACTIVITY_CONTEXT_REQUIRED -> {
            // App bug: pass an Activity to getVerifiedPhoneNumber().
            Log.e(TAG, "Firebase PNV needs an Activity context", e)
        }
        else -> {
            // Carrier not supported, network errors, and other failures.
            Log.w(TAG, "Firebase PNV failed with error code ${e.errorCode}", e)
            showSmsVerification()
        }
    }
}

この例では、showSmsVerification() はアプリの既存の電話番号確認フローです。

次のステップ