Android で Google Play Games サービスを使用して認証する

Google Play Games サービスを使用して、Firebase で構築した Android ゲームにプレーヤーをログインさせることができます。Firebase で Google Play Games サービスのログインを使用するには、まず Google Play Games でプレーヤーをログインさせ、OAuth 2.0 の認証コードをリクエストします。次に、認証コードを PlayGamesAuthProvider に渡して Firebase 認証情報を生成します。この認証情報を Firebase での認証に使用できます。

始める前に

Android プロジェクトを設定する

  1. まだ追加していない場合は、Firebase を Android プロジェクトに追加します

  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.6.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.2.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.2.0")
    }
    Kotlin 固有のライブラリ モジュールをお探しの場合、 2023 年 10 月(Firebase BoM 32.5.0)以降、Kotlin と Java のどちらのデベロッパーもメイン ライブラリ モジュールを利用できるようになります(詳しくは、このイニシアチブに関するよくある質問をご覧ください)。

Firebase プロジェクトを設定する

  1. ゲームの SHA-1 フィンガープリントを、Firebase コンソールの [設定] ページで設定します。

    次のように gradle signingReport コマンドを使用して、署名証明書の SHA ハッシュを取得できます。

    ./gradlew signingReport

  2. 次のように Google Play Games をログイン プロバイダとして有効にします。

    1. プロジェクトのウェブサーバーのクライアント ID とクライアント シークレットを見つけます。ウェブサーバーのクライアント ID は、Google Play の認証サーバーでの Firebase プロジェクトの識別に使用されます。

      これらの値は次の手順で確認できます。

      1. Google API Console の認証情報ページで Firebase プロジェクトを開きます。
      2. [OAuth 2.0 クライアント ID] セクションで、ウェブ クライアント(Google サービスで自動作成)の詳細ページを開きます。このページに、ウェブサーバーのクライアント ID とクライアント シークレットが記載されています。
    2. 次に、Firebase コンソールで、[Authentication] セクションを開きます。

    3. [Sign-in method] タブで、[Play ゲーム] ログイン プロバイダを有効にします。API Console で取得した、プロジェクトのウェブサーバーのクライアント ID とクライアント シークレットを指定する必要があります。

Firebase アプリの情報を使用して Play Games services を構成する

  1. Google Play Console で、Google Play アプリを開くか、アプリを作成します。

  2. [Grow] セクションで、Play Games services > [設定と管理] > [設定] をクリックします。

  3. [はい、ゲームで Google API をすでに使用しています] をクリックし、リストから Firebase プロジェクトを選択して [使用する] をクリックします。

  4. Play Games services の設定ページで、[認証情報を追加] をクリックします。

    1. [ゲームサーバー] のタイプを選択します。
    2. [OAuth クライアント] フィールドで、プロジェクトのウェブ クライアント ID を選択します。Play Games ログインを有効にしたときに指定したクライアント ID と同じ ID を選択してください。
    3. 変更を保存します。
  5. 引き続き Play Games services の設定ページで、もう一度 [認証情報を追加] をクリックします。

    1. [Android] のタイプを選択します。
    2. [OAuth クライアント] フィールドで、プロジェクトの Android クライアント ID を選択します(目的の Android クライアント ID が表示されない場合は、Firebase コンソールでゲームの SHA-1 フィンガープリントが設定されていることを確認してください)。
    3. 変更を保存します。
  6. [テスター] ページで、Play Store にゲームをリリースする前に、ゲームにログインできるようにするユーザーのメールアドレスを追加します。

Play Games のログインをゲームに統合する

まず、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();

ウェブサーバーのクライアント ID を requestServerAuthCode メソッドに渡す必要があります。これは、Firebase コンソールで Play ゲームのログインを有効にしたときに指定した ID です。

Firebase で認証する

Play ゲームのログインをアプリに追加したら、プレーヤーが Play ゲームへのログインに成功したときに取得する Google アカウントの認証情報を、Firebase で使用するように設定する必要があります。

  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. アクティビティを初期化するときに、プレーヤーがすでに 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 のセキュリティ ルールでは、ログイン済みユーザーの一意のユーザー ID を auth 変数から取得し、それを使用して、ユーザーがアクセス可能なデータを制御できます。

ユーザーの Play Games のプレーヤー情報を取得したり、Play Games サービスにアクセスしたりするには、Google Play Games サービス SDK で提供されている API を使用します。

ユーザーのログアウトを行うには、FirebaseAuth.signOut() を呼び出します。

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();