在 Android 上透過 Google 驗證

您可以讓使用者透過 Google 帳戶,使用 Firebase 驗證服務進行驗證。

事前準備

  1. 如果您尚未將 Firebase 新增至 Android 專案,請先新增。

  2. 模組 (應用程式層級) Gradle 檔案 (通常是 <project>/<app-module>/build.gradle.kts<project>/<app-module>/build.gradle) 中,加入 Android 適用的 Firebase Authentication 程式庫依附元件。建議使用 Firebase Android BoM 控制程式庫版本。

    此外,您也需要在設定 Firebase Authentication 時,將 Credential Manager SDK 新增至應用程式。

    dependencies {     // Import the BoM for the Firebase platform     implementation(platform("com.google.firebase:firebase-bom:34.1.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")
    // Also add the dependencies for the Credential Manager libraries and specify their versions implementation("androidx.credentials:credentials:1.3.0") implementation("androidx.credentials:credentials-play-services-auth:1.3.0") implementation("com.google.android.libraries.identity.googleid:googleid:1.1.1")
    }

    只要使用 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:24.0.1")
    // Also add the dependencies for the Credential Manager libraries and specify their versions implementation("androidx.credentials:credentials:1.3.0") implementation("androidx.credentials:credentials-play-services-auth:1.3.0") implementation("com.google.android.libraries.identity.googleid:googleid:1.1.1")
    }

  3. 如果尚未指定應用程式的 SHA 指紋,請前往 Firebase 管理中心的「設定」頁面進行設定。如要瞭解如何取得應用程式的 SHA 指紋,請參閱「驗證用戶端」。

  4. Firebase 控制台中啟用 Google 做為登入方法:
    1. Firebase 控制台中,開啟「Auth」(驗證) 部分。
    2. 在「登入方式」分頁標籤中,啟用「Google」登入方式,然後按一下「儲存」
  5. 當控制台顯示提示時,請下載更新後的 Firebase 設定檔 (google-services.json),其中現在包含 Google 登入所需的 OAuth 用戶端資訊。

  6. 將這個更新後的設定檔移至 Android Studio 專案,取代現在已過時的對應設定檔。(請參閱「將 Firebase 新增至 Android 專案」一文)。

使用 Firebase 進行驗證

  1. 按照憑證管理工具說明文件中的步驟,將「使用 Google 帳戶登入」功能整合至應用程式。以下是 高階操作說明:
    1. 使用 GetGoogleIdOption 例項化 Google 登入要求。接著,使用 GetCredentialRequest 建立 Credential Manager 要求:

      Kotlin

      // Instantiate a Google sign-in request val googleIdOption = GetGoogleIdOption.Builder()     // Your server's client ID, not your Android client ID.     .setServerClientId(getString(R.string.default_web_client_id))     // Only show accounts previously used to sign in.     .setFilterByAuthorizedAccounts(true)     .build()  // Create the Credential Manager request val request = GetCredentialRequest.Builder()     .addCredentialOption(googleIdOption)     .build()

      Java

      // Instantiate a Google sign-in request GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()         .setFilterByAuthorizedAccounts(true)         .setServerClientId(getString(R.string.default_web_client_id))         .build();  // Create the Credential Manager request GetCredentialRequest request = new GetCredentialRequest.Builder()         .addCredentialOption(googleIdOption)         .build();

      在上述要求中,您必須將「伺服器」用戶端 ID 傳遞至 setServerClientId 方法。如要尋找 OAuth 2.0 用戶端 ID,請按照下列步驟操作:

      1. Google Cloud 控制台中開啟「憑證」頁面
      2. 網頁應用程式類型的用戶端 ID 是後端伺服器的 OAuth 2.0 用戶端 ID。
    2. 整合「使用 Google 帳戶登入」功能後,請確認登入活動的程式碼類似於下列程式碼:

      Kotlin

      private fun handleSignIn(credential: Credential) {     // Check if credential is of type Google ID     if (credential is CustomCredential && credential.type == TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {         // Create Google ID Token         val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)          // Sign in to Firebase with using the token         firebaseAuthWithGoogle(googleIdTokenCredential.idToken)     } else {         Log.w(TAG, "Credential is not of type Google ID!")     } }

      Java

      private void handleSignIn(Credential credential) {     // Check if credential is of type Google ID     if (credential instanceof CustomCredential customCredential             && credential.getType().equals(TYPE_GOOGLE_ID_TOKEN_CREDENTIAL)) {         // Create Google ID Token         Bundle credentialData = customCredential.getData();         GoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credentialData);          // Sign in to Firebase with using the token         firebaseAuthWithGoogle(googleIdTokenCredential.getIdToken());     } else {         Log.w(TAG, "Credential is not of type Google ID!");     } }
  2. 在登入活動的 onCreate 方法中,取得 FirebaseAuth 物件的共用執行個體:

    Kotlin

    private lateinit var auth: FirebaseAuth // ... // Initialize Firebase Auth auth = Firebase.auth

    Java

    private FirebaseAuth mAuth; // ... // Initialize Firebase Auth mAuth = FirebaseAuth.getInstance();
  3. 初始化 Activity 時,請檢查使用者目前是否已登入:

    Kotlin

    override fun onStart() {     super.onStart()     // Check if user is signed in (non-null) and update UI accordingly.     val currentUser = auth.currentUser     updateUI(currentUser) }

    Java

    @Override public void onStart() {     super.onStart();     // Check if user is signed in (non-null) and update UI accordingly.     FirebaseUser currentUser = mAuth.getCurrentUser();     updateUI(currentUser); }
  4. 現在請取得步驟 1 中建立的使用者 Google ID 權杖,將其換成 Firebase 憑證,然後使用 Firebase 憑證向 Firebase 驗證:

    Kotlin

    private fun firebaseAuthWithGoogle(idToken: String) {     val credential = GoogleAuthProvider.getCredential(idToken, null)     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 = auth.currentUser                 updateUI(user)             } else {                 // If sign in fails, display a message to the user                 Log.w(TAG, "signInWithCredential:failure", task.exception)                 updateUI(null)             }         } }

    Java

    private void firebaseAuthWithGoogle(String idToken) {     AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);     mAuth.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");                     FirebaseUser user = mAuth.getCurrentUser();                     updateUI(user);                 } else {                     // If sign in fails, display a message to the user                     Log.w(TAG, "signInWithCredential:failure", task.getException());                     updateUI(null);                 }             }); }
    如果對 signInWithCredential 的呼叫成功,您可以使用 getCurrentUser 方法取得使用者的帳戶資料。

後續步驟

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

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

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

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

如要登出使用者,請呼叫 signOut。此外,您也需要從所有憑證提供者清除目前的使用者憑證狀態,如 Credential Manager 說明文件建議:

Kotlin

private fun signOut() {     // Firebase sign out     auth.signOut()      // When a user signs out, clear the current user credential state from all credential providers.     lifecycleScope.launch {         try {             val clearRequest = ClearCredentialStateRequest()             credentialManager.clearCredentialState(clearRequest)             updateUI(null)         } catch (e: ClearCredentialException) {             Log.e(TAG, "Couldn't clear user credentials: ${e.localizedMessage}")         }     } }

Java

private void signOut() {     // Firebase sign out     mAuth.signOut();      // When a user signs out, clear the current user credential state from all credential providers.     ClearCredentialStateRequest clearRequest = new ClearCredentialStateRequest();     credentialManager.clearCredentialStateAsync(             clearRequest,             new CancellationSignal(),             Executors.newSingleThreadExecutor(),             new CredentialManagerCallback<>() {                 @Override                 public void onResult(@NonNull Void result) {                     updateUI(null);                 }                  @Override                 public void onError(@NonNull ClearCredentialException e) {                     Log.e(TAG, "Couldn't clear user credentials: " + e.getLocalizedMessage());                 }             }); }