使用 Google Play 游戏服务进行身份验证 (Android)

您可以使用 Google Play 游戏服务,让玩家登录在 Firebase 上构建的 Android 游戏。如需使用 Google Play 游戏服务登录 Firebase,请首先让玩家登录 Google Play 游戏,并同时申请一个 OAuth 2.0 身份验证代码。然后,将此身份验证代码传递给 PlayGamesAuthProvider 以生成一个 Firebase 凭据,您可以使用该凭据进行 Firebase 身份验证。

准备工作

设置 Android 项目

  1. 将 Firebase 添加到您的 Android 项目(如果尚未添加)。

  2. 在您的模块(应用级)Gradle 文件(通常是 <project>/<app-module>/build.gradle.kts<project>/<app-module>/build.gradle)中,添加 Firebase Authentication Android 库的依赖项。我们建议使用 Firebase Android BoM 来实现库版本控制。

    此外,在设置 Firebase Authentication 时,您还需要将 Google Play 服务 SDK 添加到您的应用中。

    Kotlin+KTX

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

    Java

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

设置您的 Firebase 项目

  1. 从 Firebase 控制台的设置页面设置游戏的 SHA-1 指纹。

    您可以使用 Gradle 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 控制台中,打开 Authentication 部分。

    3. Sign in method(登录方法)标签页上,启用 Play 游戏登录提供方。您需要指定从 API 控制台中获得的您项目的 Web 服务器客户端 ID 和客户端密钥。

根据 Firebase 应用信息配置 Play 游戏服务

  1. Google Play 管理中心中,打开您的 Google Play 应用或创建一个应用。

  2. 在“拓展”部分,依次点击 Play 游戏服务 > 设置和管理 > 配置

  3. 点击是,我的游戏已经使用了 Google API,从列表中选择您的 Firebase 项目,然后点击使用

  4. 在 Play 游戏服务配置页面上,点击添加凭据

    1. 选择游戏服务器类型。
    2. OAuth 客户端字段中,选择您的项目的 Web 客户端 ID。请确保此 ID 就是您在启用 Play 游戏登录功能时指定的客户端 ID。
    3. 保存更改。
  5. 在 Play 游戏服务配置页面上,再次点击添加凭据

    1. 选择 Android 类型。
    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 方法。此 ID 就是您在 Firebase 控制台中启用 Play 游戏登录服务时提供的 ID。

进行 Firebase 身份验证

将 Play 游戏登录服务添加到您的应用后,您需要设置 Firebase,以使用您在玩家成功登录 Play 游戏时获取的 Google 帐号凭据。

  1. 首先,在登录 Activity 的 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 Realtime Database 和 Cloud Storage 安全规则中,您可以从 auth 变量获取已登录用户的唯一用户 ID,然后利用此 ID 来控制用户可以访问哪些数据。

如需获取用户的 Play 游戏玩家信息或访问 Play 游戏服务,请使用 Google Play Games SDK 提供的 API。

如需让用户退出登录,请调用 FirebaseAuth.signOut()

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();