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

您可以使用 Google Play 遊戲服務,讓玩家登入以 Firebase 建構的 Android 遊戲。如要使用 Google Play 遊戲服務登入 Firebase,請先使用 Google Play 遊戲服務登入玩家,並在登入時要求 OAuth 2.0 驗證碼。接著,將驗證碼傳遞至 PlayGamesAuthProvider,產生 Firebase 憑證,您可以使用這組憑證驗證 Firebase。

事前準備

設定 Android 專案

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

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

    此外,您還需要在設定 Firebase Authentication 時,將 Google Play 服務 SDK 新增至應用程式。

    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")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.3.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:23.1.0")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.3.0")
    }
    想尋找 Kotlin 專屬的程式庫模組嗎?2023 年 10 月 (Firebase BoM 32.5.0)起,Kotlin 和 Java 開發人員都可以依附主要程式庫模組 (詳情請參閱這項計畫的常見問題)。

設定 Firebase 專案

  1. 請在 Firebase 管理中心的「設定」頁面設定遊戲的 SHA-1 指紋。

    您可以使用 gradle signingReport 指令取得簽署憑證的 SHA 雜湊:

    ./gradlew signingReport

  2. 將 Google Play 遊戲設為登入供應商:

    1. 找出專案的網頁伺服器用戶端 ID 和用戶端密碼。網頁伺服器用戶端 ID 可向 Google Play 驗證伺服器識別您的 Firebase 專案。

      如要查看這些值,請按照下列步驟操作:

      1. Google API 控制台憑證頁面中開啟 Firebase 專案。
      2. 在「OAuth 2.0 用戶端 ID」部分,開啟「網路用戶端 (由 Google 服務自動建立)」詳細資料頁面。這個頁面會列出您的網頁伺服器用戶端 ID 和密鑰。
    2. 接著,在 Firebase 控制台中,開啟「驗證」部分。

    3. 在「Sign in method」分頁中,啟用「Play 遊戲」登入供應器。您需要指定專案的網路伺服器用戶端 ID 和用戶端密鑰,這些資訊可從 API 控制台中取得。

使用 Firebase 應用程式資訊設定 Play Games services

  1. Google Play 控制台中開啟或建立 Google Play 應用程式。

  2. 在「Grow」部分,依序點選「Play Games services」>「設定與管理」>「設定」

  3. 按一下「是,我的遊戲使用了 Google API」,從清單中選取 Firebase 專案,然後按一下「使用」

  4. Play Games services 設定頁面中,按一下「Add Credential」

    1. 選取「遊戲伺服器」類型。
    2. 在「OAuth 用戶端」欄位中,選取專案的網路用戶端 ID。請確認此 ID 與您啟用 Play Games 登入功能時指定的用戶端 ID 相同。
    3. 儲存變更。
  5. Play Games services 設定頁面中,再次按一下「Add Credential」

    1. 選取「Android」類型。
    2. 在「OAuth 用戶端」欄位中,選取專案的 Android 用戶端 ID。(如果找不到 Android 用戶端 ID,請務必在 Firebase 控制台中設定遊戲的 SHA-1 指紋)。
    3. 儲存變更。
  6. 在「測試人員」頁面中,新增所有使用者的電子郵件地址,這些使用者必須能夠登入遊戲,才能在 Play Store 上發布遊戲。

將 Play 遊戲登入功能整合至遊戲

首先,請將 Play 遊戲登入功能整合至應用程式。如需完整操作說明,請參閱「登入 Android 遊戲」。

在整合作業中,建構 GoogleSignInOptions 物件時,請使用 DEFAULT_GAMES_SIGN_IN 設定並呼叫 requestServerAuthCode

Kotlin

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();

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

使用 Firebase 進行驗證

在應用程式中加入 Play 遊戲登入功能後,您必須設定 Firebase,以便使用玩家成功登入 Play 遊戲時取得的 Google 帳戶憑證。

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

Kotlin

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

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

// 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

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 即時資料庫和 Cloud Storage 安全性規則中,您可以從 auth 變數取得已登入使用者的專屬使用者 ID,並利用該 ID 控管使用者可存取的資料。

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

如要將使用者登出,請呼叫 FirebaseAuth.signOut()

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();