在 Android 上使用電話號碼驗證 Firebase

您可以使用 Firebase Authentication 將簡訊傳送至使用者的手機,讓使用者登入。使用者使用簡訊訊息中包含的一次性代碼登入。

如要為應用程式新增電話號碼登入功能,最簡單的方法就是使用 FirebaseUI,其中包含置入式登入小工具,可實作電話號碼登入、密碼和聯合登入的登入流程。本文說明如何使用 Firebase SDK 導入電話號碼登入流程。

事前準備

  1. 如果您尚未將 Firebase 新增至 Android 專案,請新增 Firebase
  2. 模組 (應用程式層級) Gradle 檔案 (通常為 <project>/<app-module>/build.gradle.kts<project>/<app-module>/build.gradle) 中,加入 Android 的 Firebase Authentication 程式庫依附元件。建議您使用 Firebase Android BoM 來控管程式庫版本。
    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:33.7.0"))
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth")
    }

    只要使用 Firebase Android BoM,應用程式就會一律使用相容的 Firebase Android 程式庫版本。

    (替代做法)  使用 BoM 新增 Firebase 程式庫依附元件

    如果您選擇不使用 Firebase BoM,則必須在依附元件行中指定每個 Firebase 程式庫版本。

    請注意,如果您在應用程式中使用多個 Firebase 程式庫,強烈建議您使用 BoM 來管理程式庫版本,確保所有版本皆相容。

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth:23.1.0")
    }
    想尋找 Kotlin 專屬的程式庫模組嗎?2023 年 10 月 (Firebase BoM 32.5.0)起,Kotlin 和 Java 開發人員都可以依附主要程式庫模組 (詳情請參閱這項計畫的常見問題)。
  3. 如果您尚未將應用程式連結至 Firebase 專案,請透過 Firebase 主控台連結。
  4. 如果您尚未在 Firebase 主控台中設定應用程式的 SHA-1 雜湊,請完成這項操作。如要瞭解如何尋找應用程式的 SHA-1 雜湊,請參閱「 驗證您的用戶端」。

安全疑慮

雖然只使用電話號碼進行驗證很方便,但比起其他可用方法,安全性較低,因為電話號碼很容易在使用者之間轉移。此外,在有多個使用者設定檔的裝置上,任何可接收簡訊的使用者都可以使用裝置的電話號碼登入帳戶。

如果您在應用程式中使用電話號碼登入功能,應同時提供更安全的登入方式,並告知使用者使用電話號碼登入功能的安全性取捨。

為 Firebase 專案啟用電話號碼登入功能

如要透過簡訊登入使用者,您必須先為 Firebase 專案啟用電話號碼登入方法:

  1. Firebase 主控台中,開啟「驗證」部分。
  2. 在「登入方式」頁面中,啟用「電話號碼」登入方式。

啟用驗證應用程式功能

如要使用電話號碼驗證功能,Firebase 必須能夠驗證電話號碼登入要求是否來自您的應用程式。Firebase Authentication 有三種方式可達成這項目標:

  • Play Integrity API:如果使用者擁有安裝 Google Play services 的裝置,且 Firebase Authentication 可以透過 Play Integrity API 驗證裝置是否合法,則可以繼續進行電話號碼登入程序。Firebase Authentication 會在 Google 自有專案中啟用 Play Integrity API,而非在您的專案中啟用。這不會影響專案的任何 Play Integrity API 配額。您可以使用 Authentication SDK 21.2.0 以上版本 (Firebase BoM 31.4.0 以上版本) 支援 Play Integrity。

    如要使用 Play Integrity,如果您尚未指定應用程式的 SHA-256 指紋,請前往 Firebase 管理中心的專案設定進行指定。如要進一步瞭解如何取得應用程式的 SHA-256 指紋,請參閱「驗證用戶端」一文。

  • reCAPTCHA 驗證:如果無法使用 Play 安全防護,例如使用者所用裝置未安裝 Google Play servicesFirebase Authentication 會使用 reCAPTCHA 驗證來完成手機登入流程。使用者通常不必回答任何問題,就能完成 reCAPTCHA 驗證。請注意,這個流程要求您將 SHA-1 與應用程式建立關聯。這個流程也要求您的 API 金鑰不受限制,或已加入 PROJECT_ID.firebaseapp.com 的許可清單。

    觸發 reCAPTCHA 的部分情況:

    • 如果使用者的裝置未安裝 Google Play services
    • 如果應用程式並未透過 Google Play Store 發行 (使用 Authentication SDK 21.2.0 以上版本)。
    • 如果取得的 SafetyNet 權杖無效 (在 Authentication SDK 版本 < v21.2.0)。

    當您使用 SafetyNet 或 Play Integrity 進行應用程式驗證時,系統會根據 Google Play Store 判斷應用程式名稱,並將該名稱填入簡訊範本中的 %APP_NAME% 欄位。在 reCAPTCHA 觸發的情況下,%APP_NAME% 會填入 PROJECT_ID.firebaseapp.com

您可以使用 forceRecaptchaFlowForTesting 強制執行 reCAPTCHA 驗證流程。 您可以使用 setAppVerificationDisabledForTesting 停用應用程式驗證功能 (使用虛構電話號碼時)。

疑難排解

  • 使用 reCAPTCHA 進行應用程式驗證時,出現「缺少初始狀態」錯誤

    當 reCAPTCHA 流程順利完成,但未將使用者重新導向至原生應用程式時,就可能發生這種情況。如果發生這種情況,系統會將使用者重新導向至備用網址 PROJECT_ID.firebaseapp.com/__/auth/handler。在 Firefox 瀏覽器中,開啟原生應用程式連結的功能預設為停用。如果在 Firefox 中看到上述錯誤,請按照「設定 Android 版 Firefox 以開啟原生應用程式中的連結」中的步驟,啟用開啟應用程式連結的功能。

將驗證碼傳送至使用者的手機

如要啟動電話號碼登入功能,請向使用者顯示提示他們輸入電話號碼的介面。法律規定各有不同,但為了提供最佳做法並為使用者設定預期,您應告知使用者,如果他們使用電話號碼登入,可能會收到驗證簡訊,並須支付一般簡訊費用。

接著,將使用者的電話號碼傳遞至 PhoneAuthProvider.verifyPhoneNumber 方法,要求 Firebase 驗證使用者的電話號碼。例如:

Kotlin

val options = PhoneAuthOptions.newBuilder(auth)
    .setPhoneNumber(phoneNumber) // Phone number to verify
    .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
    .setActivity(this) // Activity (for callback binding)
    .setCallbacks(callbacks) // OnVerificationStateChangedCallbacks
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

Java

PhoneAuthOptions options = 
  PhoneAuthOptions.newBuilder(mAuth) 
      .setPhoneNumber(phoneNumber)       // Phone number to verify
      .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
      .setActivity(this)                 // (optional) Activity for callback binding
      // If no activity is passed, reCAPTCHA verification can not be used.
      .setCallbacks(mCallbacks)          // OnVerificationStateChangedCallbacks
      .build();
  PhoneAuthProvider.verifyPhoneNumber(options);     

verifyPhoneNumber 方法是可重入的:如果您多次呼叫該方法 (例如在活動的 onStart 方法中),verifyPhoneNumber 方法不會傳送第二次簡訊,除非原始要求已逾時。

如果應用程式在使用者登入前關閉 (例如使用者正在使用簡訊應用程式時),您可以使用這項行為來繼續電話號碼登入程序。呼叫 verifyPhoneNumber 後,請設定標記,指出驗證程序正在進行中。接著,請在活動的 onSaveInstanceState 方法中儲存標記,並在 onRestoreInstanceState 中還原標記。最後,在活動的 onStart 方法中,檢查驗證是否已進行中,如果是,請再次呼叫 verifyPhoneNumber。請務必在驗證完成或失敗時清除標記 (請參閱「 驗證回呼」)。

如要輕鬆處理螢幕旋轉和其他活動重新啟動例項,請將活動傳遞至 verifyPhoneNumber 方法。當活動停止時,回呼會自動分離,因此您可以在回呼方法中自由編寫 UI 轉場程式碼。

您也可以透過 Auth 例項上的 setLanguageCode 方法指定驗證語言,藉此將 Firebase 傳送的簡訊本地化。

Kotlin

auth.setLanguageCode("fr")
// To apply the default app language instead of explicitly setting it.
// auth.useAppLanguage()

Java

auth.setLanguageCode("fr");
// To apply the default app language instead of explicitly setting it.
// auth.useAppLanguage();

呼叫 PhoneAuthProvider.verifyPhoneNumber 時,您也必須提供 OnVerificationStateChangedCallbacks 的例項,其中包含回呼函式的實作項目,可處理要求的結果。例如:

Kotlin

callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    override fun onVerificationCompleted(credential: PhoneAuthCredential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:$credential")
        signInWithPhoneAuthCredential(credential)
    }

    override fun onVerificationFailed(e: FirebaseException) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e)

        if (e is FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e is FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        } else if (e is FirebaseAuthMissingActivityForRecaptchaException) {
            // reCAPTCHA verification attempted with null Activity
        }

        // Show a message and update the UI
    }

    override fun onCodeSent(
        verificationId: String,
        token: PhoneAuthProvider.ForceResendingToken,
    ) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:$verificationId")

        // Save verification ID and resending token so we can use them later
        storedVerificationId = verificationId
        resendToken = token
    }
}

Java

mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    @Override
    public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:" + credential);

        signInWithPhoneAuthCredential(credential);
    }

    @Override
    public void onVerificationFailed(@NonNull FirebaseException e) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e);

        if (e instanceof FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e instanceof FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        } else if (e instanceof FirebaseAuthMissingActivityForRecaptchaException) {
            // reCAPTCHA verification attempted with null Activity
        }

        // Show a message and update the UI
    }

    @Override
    public void onCodeSent(@NonNull String verificationId,
                           @NonNull PhoneAuthProvider.ForceResendingToken token) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:" + verificationId);

        // Save verification ID and resending token so we can use them later
        mVerificationId = verificationId;
        mResendToken = token;
    }
};

驗證回呼

在大多數應用程式中,您會實作 onVerificationCompletedonVerificationFailedonCodeSent 回呼。視應用程式需求而定,您也可以實作 onCodeAutoRetrievalTimeOut

onVerificationCompleted(PhoneAuthCredential)

這個方法會在兩種情況下呼叫:

  • 即時驗證:在某些情況下,系統可以立即驗證電話號碼,而不需要傳送或輸入驗證碼。
  • 自動擷取:在部分裝置上,Google Play 服務可自動偵測傳入的驗證簡訊,並在使用者不必採取任何動作的情況下執行驗證。(部分電信業者可能無法提供這項功能)。這會使用 SMS Retriever API,該 API 會在 SMS 訊息結尾加上 11 個字元的雜湊。
無論是哪種情況,使用者的電話號碼都已成功驗證,您可以使用傳遞至回呼的 PhoneAuthCredential 物件,登入使用者

onVerificationFailed(FirebaseException)

系統會在收到無效的驗證要求時呼叫這個方法,例如指定無效電話號碼或驗證碼的要求。

onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken)

選用設定。系統會在透過簡訊將驗證碼傳送至提供的電話號碼後,呼叫這個方法。

呼叫這個方法時,大多數應用程式都會顯示 UI,提示使用者輸入簡訊中的驗證碼。(同時,系統可能會在背景執行自動驗證作業)。接著,在使用者輸入驗證碼後,您可以使用驗證碼和傳遞至方法的驗證 ID 建立 PhoneAuthCredential 物件,然後使用該物件登入使用者。不過,部分應用程式可能會等到呼叫 onCodeAutoRetrievalTimeOut 後,才會顯示驗證碼 UI (不建議使用)。

onCodeAutoRetrievalTimeOut(String verificationId)

選用設定。系統會在 verifyPhoneNumber 指定的逾時時間長度過後,且未先觸發 onVerificationCompleted 時呼叫此方法。在沒有 SIM 卡的裝置上,由於無法自動擷取簡訊,因此系統會立即呼叫此方法。

有些應用程式會在自動驗證期間逾時前封鎖使用者輸入內容,然後才顯示 UI,提示使用者輸入簡訊中的驗證碼 (不建議使用)。

建立 PhoneAuthCredential 物件

使用者輸入 Firebase 傳送至使用者手機的驗證碼後,請使用驗證碼和傳遞至 onCodeSentonCodeAutoRetrievalTimeOut 回呼的驗證 ID,建立 PhoneAuthCredential 物件。(呼叫 onVerificationCompleted 時,您會直接取得 PhoneAuthCredential 物件,因此可以略過這個步驟)。

如要建立 PhoneAuthCredential 物件,請呼叫 PhoneAuthProvider.getCredential

Kotlin

val credential = PhoneAuthProvider.getCredential(verificationId!!, code)

Java

PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);

登入使用者帳戶

取得 PhoneAuthCredential 物件後 (無論是在 onVerificationCompleted 回呼中,還是透過呼叫 PhoneAuthProvider.getCredential),請將 PhoneAuthCredential 物件傳遞至 FirebaseAuth.signInWithCredential,完成登入流程:

Kotlin

private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
    auth.signInWithCredential(credential)
        .addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                // Sign in success, update UI with the signed-in user's information
                Log.d(TAG, "signInWithCredential:success")

                val user = task.result?.user
            } else {
                // Sign in failed, display a message and update the UI
                Log.w(TAG, "signInWithCredential:failure", task.exception)
                if (task.exception is FirebaseAuthInvalidCredentialsException) {
                    // The verification code entered was invalid
                }
                // Update UI
            }
        }
}

Java

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        // Sign in success, update UI with the signed-in user's information
                        Log.d(TAG, "signInWithCredential:success");

                        FirebaseUser user = task.getResult().getUser();
                        // Update UI
                    } else {
                        // Sign in failed, display a message and update the UI
                        Log.w(TAG, "signInWithCredential:failure", task.getException());
                        if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                            // The verification code entered was invalid
                        }
                    }
                }
            });
}

使用虛構的電話號碼進行測試

您可以透過 Firebase 控制台設定虛構的電話號碼,用於開發作業。使用虛構的電話號碼進行測試可帶來以下好處:

  • 在不消耗使用配額的情況下測試電話號碼驗證。
  • 在不傳送實際簡訊的情況下,測試電話號碼驗證功能。
  • 使用相同的電話號碼連續執行測試,且不會受到頻寬限制。這樣一來,如果審查人員剛好使用相同的電話號碼進行測試,應用程式商店審查程序就不會遭到拒絕。
  • 無需額外付出任何努力,即可在開發環境中輕鬆測試,例如在 iOS 模擬器或 Android 模擬器中開發,而無需 Google Play 服務。
  • 編寫整合測試時,不會受到實際電話號碼在實際環境中通常會受到的安全檢查阻擋。

虛構的電話號碼必須符合下列規定:

  1. 請務必使用虛構的電話號碼,且該號碼不應已存在。Firebase Authentication 不允許您將真實使用者使用的現有電話號碼設為測試號碼。您可以使用開頭為 555 的號碼做為美國測試電話號碼,例如: +1 650-555-3434
  2. 電話號碼的長度和其他限制條件必須符合正確的格式。這類號碼仍須通過與真實使用者電話號碼相同的驗證程序。
  3. 您最多可以新增 10 個開發用電話號碼。
  4. 使用不易猜測且經常變更的測試電話號碼/驗證碼。

建立虛構的電話號碼和驗證碼

  1. Firebase 主控台中,開啟「驗證」部分。
  2. 在「登入方式」分頁中,啟用電話服務供應商 (如果尚未啟用的話)。
  3. 開啟「測試用電話號碼」摺疊式選單。
  4. 提供要測試的電話號碼,例如:+1 650-555-3434
  5. 請提供該特定號碼的 6 位數驗證碼,例如:654321
  6. 新增電話號碼。如有需要,您可以將滑鼠游標懸停在對應的資料列上,然後點選垃圾桶圖示,即可刪除電話號碼和代碼。

手動測試

您可以在應用程式中直接開始使用虛構的電話號碼。這樣一來,您就能在開發階段執行手動測試,而不必擔心會發生配額問題或頻寬限制。您也可以直接在未安裝 Google Play 服務的 iOS 模擬器或 Android 模擬器中進行測試。

當您提供虛構的電話號碼並傳送驗證碼時,系統不會傳送實際的簡訊。您必須提供先前設定的驗證碼,才能完成登入程序。

登入完成後,系統會使用該電話號碼建立 Firebase 使用者。使用者具有與實際電話號碼使用者相同的行為和屬性,且可以相同方式存取 Realtime Database/Cloud Firestore 和其他服務。這個程序中產生的 ID 權杖,其簽章與真實電話號碼使用者相同。

如果您想進一步限制存取權,另一個做法是透過自訂聲明設定測試角色,將這些使用者視為假使用者。

如要手動觸發 reCAPTCHA 流程進行測試,請使用 forceRecaptchaFlowForTesting() 方法。

// Force reCAPTCHA flow
FirebaseAuth.getInstance().getFirebaseAuthSettings().forceRecaptchaFlowForTesting();

整合測試

除了手動測試之外,Firebase Authentication 也提供 API,協助您為電話驗證測試編寫整合測試。這些 API 會停用網頁版 reCAPTCHA 要求和 iOS 中的靜默推播通知,藉此停用應用程式驗證功能。這樣一來,您就能在這些流程中進行自動化測試,並更輕鬆地實作。此外,這些測試還可協助您在 Android 上測試即時驗證流程。

在 Android 上,請先呼叫 setAppVerificationDisabledForTesting(),再呼叫 signInWithPhoneNumber。這麼做會自動停用應用程式驗證功能,讓您無須手動解決問題,即可傳送電話號碼。即使已停用 Play Integrity 和 reCAPTCHA,使用真實電話號碼仍無法完成登入程序。這個 API 只能搭配虛構的電話號碼使用。

// Turn off phone auth app verification.
FirebaseAuth.getInstance().getFirebaseAuthSettings()
   .setAppVerificationDisabledForTesting();

使用虛構號碼呼叫 verifyPhoneNumber 會觸發 onCodeSent 回呼,您必須提供相應的驗證碼。這樣一來,您就可以在 Android 模擬器中進行測試。

Java

String phoneNum = "+16505554567";
String testVerificationCode = "123456";

// Whenever verification is triggered with the whitelisted number,
// provided it is not set for auto-retrieval, onCodeSent will be triggered.
FirebaseAuth auth = FirebaseAuth.getInstance();
PhoneAuthOptions options = PhoneAuthOptions.newBuilder(auth)
        .setPhoneNumber(phoneNum)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onCodeSent(@NonNull String verificationId,
                                   @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
                // Save the verification id somewhere
                // ...

                // The corresponding whitelisted code above should be used to complete sign-in.
                MainActivity.this.enableUserManuallyInputCode();
            }

            @Override
            public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
                // Sign in with the credential
                // ...
            }

            @Override
            public void onVerificationFailed(@NonNull FirebaseException e) {
                // ...
            }
        })
        .build();
PhoneAuthProvider.verifyPhoneNumber(options);

Kotlin

val phoneNum = "+16505554567"
val testVerificationCode = "123456"

// Whenever verification is triggered with the whitelisted number,
// provided it is not set for auto-retrieval, onCodeSent will be triggered.
val options = PhoneAuthOptions.newBuilder(Firebase.auth)
    .setPhoneNumber(phoneNum)
    .setTimeout(30L, TimeUnit.SECONDS)
    .setActivity(this)
    .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

        override fun onCodeSent(
            verificationId: String,
            forceResendingToken: PhoneAuthProvider.ForceResendingToken,
        ) {
            // Save the verification id somewhere
            // ...

            // The corresponding whitelisted code above should be used to complete sign-in.
            this@MainActivity.enableUserManuallyInputCode()
        }

        override fun onVerificationCompleted(phoneAuthCredential: PhoneAuthCredential) {
            // Sign in with the credential
            // ...
        }

        override fun onVerificationFailed(e: FirebaseException) {
            // ...
        }
    })
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

此外,您也可以透過呼叫 setAutoRetrievedSmsCodeForPhoneNumber,設定虛構號碼和相應的驗證碼,以便在 Android 中測試自動擷取流程。

呼叫 verifyPhoneNumber 時,會直接使用 PhoneAuthCredential 觸發 onVerificationCompleted。這項功能僅適用於虛構的電話號碼。

請務必停用這項功能,並在將應用程式發布至 Google Play 商店時,確保應用程式中沒有硬式編碼的虛構電話號碼。

Java

// The test phone number and code should be whitelisted in the console.
String phoneNumber = "+16505554567";
String smsCode = "123456";

FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
FirebaseAuthSettings firebaseAuthSettings = firebaseAuth.getFirebaseAuthSettings();

// Configure faking the auto-retrieval with the whitelisted numbers.
firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode);

PhoneAuthOptions options = PhoneAuthOptions.newBuilder(firebaseAuth)
        .setPhoneNumber(phoneNumber)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
                // Instant verification is applied and a credential is directly returned.
                // ...
            }

            // ...
        })
        .build();
PhoneAuthProvider.verifyPhoneNumber(options);

Kotlin

// The test phone number and code should be whitelisted in the console.
val phoneNumber = "+16505554567"
val smsCode = "123456"

val firebaseAuth = Firebase.auth
val firebaseAuthSettings = firebaseAuth.firebaseAuthSettings

// Configure faking the auto-retrieval with the whitelisted numbers.
firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode)

val options = PhoneAuthOptions.newBuilder(firebaseAuth)
    .setPhoneNumber(phoneNumber)
    .setTimeout(60L, TimeUnit.SECONDS)
    .setActivity(this)
    .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
        override fun onVerificationCompleted(credential: PhoneAuthCredential) {
            // Instant verification is applied and a credential is directly returned.
            // ...
        }

        // ...
    })
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

後續步驟

使用者首次登入後,系統會建立新使用者帳戶,並連結至使用者登入時所用的憑證 (即使用者名稱和密碼、電話號碼或驗證服務提供者資訊)。這個新帳戶會儲存在 Firebase 專案中,無論使用者如何登入,都可以用於在專案中的每個應用程式中識別使用者。

  • 在應用程式中,您可以從 FirebaseUser 物件取得使用者的個人資料基本資訊。請參閱「 管理使用者」。

  • Firebase Realtime DatabaseCloud Storage 安全性規則中,您可以從 auth 變數取得已登入使用者的專屬使用者 ID,並利用該 ID 控管使用者可存取的資料。

您可以將驗證服務供應商憑證連結至現有使用者帳戶,讓使用者使用多個驗證服務供應商登入應用程式。

如要將使用者登出,請呼叫 signOut

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();