在 Android 上使用 Google Play 遊戲服務進行身份驗證

您可以使用 Google Play 遊戲服務讓玩家登入基於 Firebase 建置的 Android 遊戲。若要透過 Firebase 使用 Google Play 遊戲服務登錄,請先使用 Google Play 遊戲登入玩家,然後在執行此操作時要求 OAuth 2.0 驗證程式碼。然後,將身份驗證程式碼傳遞給PlayGamesAuthProvider以產生 Firebase 憑證,您可以使用該憑證透過 Firebase 進行身份驗證。

在你開始之前

設定您的 Android 項目

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

  2. 模組(應用程式層級)Gradle 檔案(通常<project>/<app-module>/build.gradle.kts<project>/<app-module>/build.gradle )中,新增Firebase 驗證的依賴項Android 的庫。我們建議使用Firebase Android BoM來控制函式庫版本控制。

    此外,作為設定 Firebase 驗證的一部分,您需要將 Google Play 服務 SDK 新增至您的應用程式。

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:32.7.4"))
    
        // 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 dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.0.0")
    }

    透過使用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:22.3.1")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.0.0")
    }
    正在尋找 Kotlin 特定的庫模組?2023 年 10 月(Firebase BoM 32.5.0)開始,Kotlin 和 Java 開發人員都可以依賴主庫模組(有關詳細信息,請參閱有關此計劃的常見問題解答)。

設定您的 Firebase 項目

  1. 從 Firebase 控制台的「設定」頁面設定遊戲的 SHA-1 指紋。

    您可以使用signingReport指令來取得簽章憑證的 SHA 雜湊值:

    ./gradlew signingReport

  2. 啟用 Google Play 遊戲作為登入提供者:

    1. 尋找專案的 Web 伺服器客戶端 ID 和客戶端金鑰。 Web 伺服器用戶端 ID 向 Google Play 驗證伺服器識別您的 Firebase 專案。

      要找到這些值:

      1. Google API 控制台憑證頁面中開啟您的 Firebase 專案。
      2. OAuth 2.0 用戶端 ID部分中,開啟Web 用戶端(由 Google 服務自動建立)詳細資訊頁面。此頁面列出了您的 Web 伺服器用戶端 ID 和密碼。
    2. 然後,在Firebase 控制台中,開啟「驗證」部分。

    3. 登入方法標籤上,啟用Play 遊戲登入提供者。您需要指定專案的 Web 伺服器用戶端 ID 和用戶端金鑰,這些資訊是從 API 控制台取得的。

使用您的 Firebase 應用程式資訊設定 Play 遊戲服務

  1. Google Play 管理中心中,開啟您的 Google Play 應用程式或建立一個。

  2. 「發展」部分中,點選Play 遊戲服務 > 設定與管理 > 設定

  3. 點擊是,我的遊戲已使用 Google API ,從清單中選擇您的 Firebase 項目,然後點擊使用

  4. 在 Play 遊戲服務設定頁面上,點選新增憑證

    1. 選擇遊戲伺服器類型。
    2. OAuth 用戶端欄位中,選擇專案的 Web 用戶端 ID。確保這與您啟用 Play 遊戲登入時指定的用戶端 ID 相同。
    3. 儲存您的變更。
  5. 仍在 Play 遊戲服務設定頁面上,再次點選新增憑證

    1. 選擇安卓類型。
    2. OAuth 用戶端欄位中,選擇專案的 Android 用戶端 ID。 (如果您沒有看到 Android 用戶端 ID,請務必在 Firebase 控制台中設定遊戲的 SHA-1 指紋。)
    3. 儲存您的變更。
  6. 「測試人員」頁面上,新增在 Play 商店上發布遊戲之前需要能夠登入遊戲的所有使用者的電子郵件地址。

將 Play 遊戲登入整合到您的遊戲中

首先,將 Play 遊戲登入整合到您的應用中。請參閱登入 Android 遊戲以了解完整說明。

在整合中,當您建立GoogleSignInOptions物件時,請使用DEFAULT_GAMES_SIGN_IN配置並呼叫requestServerAuthCode

Kotlin+KTX

val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
    .requestServerAuthCode(getString(R.string.default_web_client_id))
    .build()

Java

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
        .requestServerAuthCode(getString(R.string.default_web_client_id))
        .build();

您必須將 Web 伺服器客戶端 ID 傳遞給requestServerAuthCode方法。這是您在 Firebase 控制台中啟用 Play 遊戲登入時提供的 ID。

使用 Firebase 進行身份驗證

將 Play 遊戲登入新增至您的應用程式後,您需要將 Firebase 設定為使用玩家透過 Play 遊戲成功登入時獲得的 Google 帳戶憑證。

  1. 首先,在登入活動的onCreate方法中,取得FirebaseAuth物件的共用實例:

Kotlin+KTX

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

Java

private FirebaseAuth mAuth;
// ...
// Initialize Firebase Auth
mAuth = FirebaseAuth.getInstance();
  1. 初始化您的 Activity 時,請檢查玩家是否已使用 Firebase 登入:

Kotlin+KTX

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);
}
If the player isn't signed in, present the player with your game's
signed-out experience, including the option to sign in.
  1. 玩家以靜默方式或互動方式登入 Play 遊戲後,從GoogleSignInAccount物件取得身分驗證程式碼,將其交換為 Firebase 憑證,然後使用 Firebase 憑證透過 Firebase 進行驗證:

Kotlin+KTX

// Call this both in the silent sign-in task's OnCompleteListener and in the
// Activity's onActivityResult handler.
private fun firebaseAuthWithPlayGames(acct: GoogleSignInAccount) {
    Log.d(TAG, "firebaseAuthWithPlayGames:" + acct.id!!)

    val auth = Firebase.auth
    val credential = PlayGamesAuthProvider.getCredential(acct.serverAuthCode!!)
    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)
                Toast.makeText(
                    baseContext,
                    "Authentication failed.",
                    Toast.LENGTH_SHORT,
                ).show()
                updateUI(null)
            }

            // ...
        }
}

Java

// Call this both in the silent sign-in task's OnCompleteListener and in the
// Activity's onActivityResult handler.
private void firebaseAuthWithPlayGames(GoogleSignInAccount acct) {
    Log.d(TAG, "firebaseAuthWithPlayGames:" + acct.getId());

    final FirebaseAuth auth = FirebaseAuth.getInstance();
    AuthCredential credential = PlayGamesAuthProvider.getCredential(acct.getServerAuthCode());
    auth.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 = auth.getCurrentUser();
                        updateUI(user);
                    } else {
                        // If sign in fails, display a message to the user.
                        Log.w(TAG, "signInWithCredential:failure", task.getException());
                        Toast.makeText(MainActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                        updateUI(null);
                    }

                    // ...
                }
            });
}

如果呼叫signInWithCredential成功,您可以使用getCurrentUser方法取得使用者的帳戶資料。

下一步

用戶首次登入後,系統會建立一個新用戶帳戶並將其連結到其 Play 遊戲 ID。這個新帳戶將作為 Firebase 專案的一部分存儲,可用於識別專案中每個應用程式中的使用者。

在您的遊戲中,您可以從FirebaseUser物件取得使用者的 Firebase UID:

Kotlin+KTX

val user = auth.currentUser
user?.let {
    val playerName = it.displayName

    // The user's Id, unique to the Firebase project.
    // Do NOT use this value to authenticate with your backend server, if you
    // have one; use FirebaseUser.getIdToken() instead.
    val uid = it.uid
}

Java

FirebaseUser user = mAuth.getCurrentUser();
String playerName = user.getDisplayName();

// The user's Id, unique to the Firebase project.
// Do NOT use this value to authenticate with your backend server, if you
// have one; use FirebaseUser.getIdToken() instead.
String uid = user.getUid();

在 Firebase 即時資料庫和雲端儲存安全性規則中,您可以從auth變數取得登入使用者的唯一使用者 ID,並使用它來控制使用者可以存取哪些資料。

若要取得使用者的 Play 遊戲玩家資訊或存取 Play 遊戲服務,請使用Google Play 遊戲 SDK提供的 API 。

若要登出用戶,請呼叫FirebaseAuth.signOut()

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();