Android

【Unity】Androidネイティブ連携で、Credential Managerを使ってGoogle認証を実装する方法

UnityでGoogle認証を実装する場合、Google公式のライブラリを利用するのが一般的です。

しかし、最終更新日が5年ぐらい前で、最新のFirebaseライブラリーと組み合わせて使うともう、動きません。

この問題を解消するため、Androidネイティブ連携でGoogle認証を行う方法と、認証した結果をUnity用のFirebaseAuthライブラリーと連携させる方法を詳しく解説します。

また、Androidのネイティブ環境でGoogle認証を実装する場合「Android向けGoogleログイン」と公式が呼んでいるGoogle Sign Inライブラリーを使うのが一般的でしたがdeprecatedとなりライブラリーから削除される事も決定しているため、本記事では新しい方式である「認証情報マネージャー」を使った実装方法を解説します。

以前の Google ログインから Credential Manager と AuthorizationClient に移行する
https://developer.android.com/identity/sign-in/legacy-gsi-migration?hl=ja

 

iOSネイティブ連携でGoogle認証を実装する方法はコチラ

【Unity】iOSネイティブ連携でGoogle Sign Inを実装する方法UnityでGoogle Sign Inを実装する場合、Google公式のライブラリを利用するのが一般的です。 しかし、最...

 

Firebaseの用意

Firebaseにアプリ用のプロジェクトを作成したらUnityアプリとして登録し、Androidの欄に必要項目を記入します。

そして、Unity側で呼ぶFirebaseAuthとAndroidネイティブのGoogleアカウントを紐付けるための準備をしていきます。

 

Google認証の有効化

「構築」欄のAuthenticationを選び、「新しいプロバイダを追加」からGoogleを選び、Google認証を有効にします。

フィンガープリントの登録

Google認証をするには、Firebaseプロジェクトにフィンガープリントを登録する必要があります。

登録する場所は、該当アプリのFirebaseプロジェクトを開き、左上の設定アイコンを押して「プロジェクトの設定」

下の方にスクロールすると「SHA証明書フィンガープリント」という欄があるので「フィンガープリントを追加」で追加します。

デバッグ環境用のフィンガープリントは、ターミナルを開き次のコマンドを叩くことで取得できます。

キーストアのパスワードは「android」です。

// Mac
keytool -list -v -keystore ~/.android/debug.keystore

// Windows
keytool -list -v -keystore %USERPROFILE%\.android\debug.keystore

 

FirebaseのSHA証明書フィンガープリントを記入する欄には「SHA-1」と書いていますが、デバッグ環境用にはMD5の方を入れてください。
なぜかわからないですがMD5の方じゃないとダメです。なぜなのでしょうか。。

本番用のフィンガープリントは、Google Play Consoleで該当アプリを開き
テストとリリース > 設定 > アプリの署名 > アプリ署名鍵の証明書 > SHA1 証明書のフィンガープリント
に記載があります。

Google PlayにまだAndroidアプリを登録していない場合は、まず登録をしてから上記を確認してみてください。

設定ファイルの配置

全ての準備が完了したら、Firebase管理画面の左上にある歯車ボタンを押して、プロジェクトの設定を選び、google-services.jsonをダウンロードしたら、UnityプロジェクトのAssetsフォルダに配置します。

 

AndroidネイティブでGoogle認証

では、AndroidネイティブのGoogle Sign Inを実装していきましょう。
まず、File > Build Settingsで、PlatformをAndroidに切り替えておきます。

AndroidネイティブはActivityというもので画面が構成されているのですが、Unityの場合、Activityを継承してUnityに必要な処理を追加した「UnityPlayerActivity」がアプリの起動と同時に呼び出されます。

このUnityPlayerActivityを、独自Activityに差し替え、そこにGoogle認証を実装することでUnityでのGoogle認証を実現します。

独自Activityの実装

という訳で早速、UnityPlayerActivityを継承した独自Activityを作ってGoogle認証を実装していきます。

最初に書いたように旧式のGoogle Sign Inライブラリではなく、Credential Managerを使います。

コードの詳細は全部コメントに書いたのでそちらを参照してください。
UnityPlayer.UnitySendMessageの第1引数は、Sign Inの結果を受け取るUnity側のクラス名を指定します。各自自分の環境に書き換えてください。(今回はTestController)
コードはJavaで書いてください。Kotlinだと動きません。

package jp.toconakis.eureka5;
import com.unity3d.player.UnityPlayerActivity;
import android.os.Bundle;
import android.util.Log;

// For Credential Manager API
import androidx.annotation.NonNull;
import androidx.credentials.CredentialManager;
import androidx.credentials.CustomCredential;
import androidx.credentials.GetCredentialRequest;
import androidx.credentials.GetCredentialResponse;
import androidx.credentials.exceptions.GetCredentialException;
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption;
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential;
import androidx.credentials.CredentialManagerCallback;
import android.os.CancellationSignal;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;


import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;
import com.unity3d.player.UnityPlayer;

public class MyActivity extends UnityPlayerActivity {
    public void signInWithGoogle() {
        // google-services.jsonの client > oauth_client > client_id の値をコピペする
    	GetSignInWithGoogleOption googleIdOption = new GetSignInWithGoogleOption.Builder(
                "1234567-nejdtuaef7aq6pb83e3i90g3vc87fnv4.apps.googleusercontent.com"
        ).build();
        GetCredentialRequest request = new GetCredentialRequest.Builder()
                .addCredentialOption(googleIdOption)
                .build();
        CredentialManager credentialManager = CredentialManager.create(this);
        
        Executor executor = Executors.newSingleThreadExecutor();
        CancellationSignal cancellationSignal = new CancellationSignal();

        credentialManager.getCredentialAsync(
            this,
            request,
            cancellationSignal,
            executor,
            new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
                @Override
                public void onResult(GetCredentialResponse result) {
                    if (result.getCredential() instanceof CustomCredential) {
                        CustomCredential credential = (CustomCredential) result.getCredential();

                        if (GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL.equals(credential.getType())) {
                            GoogleIdTokenCredential googleIdTokenCredential =
                                    GoogleIdTokenCredential.createFrom(credential.getData());

                            String idToken = googleIdTokenCredential.getIdToken();

                            // 成功: idTokenをUnityに渡す
                            UnityPlayer.UnitySendMessage("TestController", "GetIDToken", idToken);
                            return;
                        }
                    }
                    
                    // 期待した認証が得られなかった場合
                    UnityPlayer.UnitySendMessage("TestController", "GetIDTokenFailed", "Unexpected credential type.");
                }
        
                @Override
                public void onError(GetCredentialException e) {
                    // エラー
                    UnityPlayer.UnitySendMessage("TestController", "GetIDTokenFailed", e.getMessage());
                }
            }
        );
    }


    protected void onCreate(Bundle savedInstanceState) {
        // UnityPlayerActivity.onCreate() を呼び出す
        super.onCreate(savedInstanceState);

        // logcat にデバッグメッセージをプリントする
        Log.d("OverrideActivity", "onCreate called!");
    }

    public void onBackPressed() {
        // UnityPlayerActivity.onBackPressed() を呼び出す代わりに、Back ボタンイベントを無視する
        // super.onBackPressed();
    }
}

 

 

この独自Activityを、以下の場所に保存します。
赤字の部分は自分のpackage名に合わせて変更してください。

Assets/Plugins/Android/jp/toconakis/eureka5/MyActivity.java

 

各種設定ファイルの修正

次に、独自Activityの方を起動時に呼び出すよう、起動情報を定義してあるAndroidManifest.xmlの書き換え、と、Credential ManagerライブラリーをAndroid側にインストールするため、Androidのライブラリーを管理しているgradleファイルの書き換えを行います。
(必要に応じて、gradle propertiesの書き換えも)

ただ、上記の設定ファイルはデフォルトでは表示されないのでUnityを開き
Edit > Project Settings… でProject Settingsウインドウを開き
左のリストからPlayerを選んだら、Androidタブを選択して、Publishing Settings欄にある以下3つの項目にチェックを入れて必要な設定ファイルを追加します。

  • Custom Main Manifest
  • Custom Main Gradle Template
  • Custom Gradle Properties Template

AndroidManifest.xmlの修正

Assets/Plugins/Android にAndroidManifest.xmlが追加されるので、独自Activityが起動時に呼び出されるよう、activityタグの部分を修正します。(8行目あたり)

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    xmlns:tools="http://schemas.android.com/tools">
    <application>
        <!-- com.unity3d.player.UnityPlayerActivity から jp.toconakis.catcrane.MyActivityに書き換える -->
        <activity android:name="jp.toconakis.catcrane.MyActivity"
                  android:theme="@style/UnityThemeSelector">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
</manifest>

 

mainTemplate.gradleの修正

同様に、Assets/Plugins/Android にmainTemplate.gradleが追加されているので、Credential Managerを使ったGoogle Sign Inに必要な3つのライブラリーをdependenciesの欄に追記します。

apply plugin: 'com.android.library'
**APPLY_PLUGINS**

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // 認証情報マネージャーライブラリー
    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'

...

 

gradleTemplate.propertiesの修正

同様に、Assets/Plugins/Android にgradleTemplate.propertiesが追加されているので、2つの設定を追記します。

この設定は、他のプロジェクトでは自動で追加されていたのですが、今回記事のために作業してみたプロジェクトでは自動で追加されていませんでした。

どうしたら自動追加されるのか不明なので、もし既に追加されていた場合は無視してください。

  • android.useAndroidX=true
  • android.enableJetifier=true
org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M
org.gradle.parallel=true
android.enableR8=**MINIFY_WITH_R_EIGHT**
unityStreamingAssets=**STREAMING_ASSETS**
**ADDITIONAL_PROPERTIES**
# 2つのプロパティを追加
android.useAndroidX=true
android.enableJetifier=true

 

以上でAndroidネイティブ側の実装は完了なので、試しに実機でAndroidビルドを起動してみてください。

問題なく起動するはずです。

 

Unity用FirebaseAuthと連携

次に、Unity側にFirebaseAuthパッケージを導入して、Androidネイティブで成功したGoogle Sign Inの結果をFirebase Authに紐付ける処理を実装していきます。

FirebaseAuthパッケージの導入

以下のリンクから最新版のFirebase Unity SDKをダウンロードします。
今回は、2025/3時点で最新のバージョン12.7.0を導入します。

既に他のFirebaseパッケージを導入済の場合は同じバージョンのFirebaseAuthパッケージを入れるか、最新のパッケージを全て入れ直してください。
そうしないとエラーで動きません。

ダウンロードしたら解凍して、FirebaseAuth.unitypackage をimportします。

AndroidのMinimum API Levelが低すぎるとこのあとビルドが通らなくなるので、Edit > Player Settings… でProject Settingsウインドウを開き、左のリストからPlayerを選んだら、Other Settings欄にあるMinimum API LevelをAPI Level 34以上にしてください。

2024年8月31日から、API34以上じゃないと審査も通りません。

Google Play の対象 API レベル要件を満たす
https://developer.android.com/google/play/requirements/target-sdk?hl=ja

 

C#の実装

Androidネイティブの独自Activityで、UnityのTestControllerのメソッドを呼び出すよう実装していたので、クラス名はTestControllerとします。

TestControllerに定義したSignInWithGoogleメソッドをButtonなどに当てて呼び出すと、Android側のGoogle Sign Inが実行され、結果がUnity側のメソッドを通して返ってきます。

詳細はコードのコメントを参照してください。

using UnityEngine;
using Firebase.Auth;
using Firebase.Extensions;

public class TestController : MonoBehaviour
{
    private FirebaseAuth auth;
    Firebase.DependencyStatus dependencyStatus = Firebase.DependencyStatus.UnavailableOther;

    private void Start()
    {
        // FirebaseAuthの初期化
        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>
        {
            dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available)
            {
                auth = FirebaseAuth.DefaultInstance;
            }
            else
            {
                Debug.Log($"error: {dependencyStatus}");
            }
        });
    }

    // Androidに定義してあるメソッドを呼ぶ
    public void SignInWithGoogle()
    {
        // AndroidのActivityを取得する
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

        // Androidの独自Activityに定義しているメソッドを呼び出す
        activity.Call("signInWithGoogle");
    }

    // Androidから呼び出される。Google Sign Inで取得したIDTokenを受け取る
    public void GetIDToken(string idToken)
    {
        Credential credencial = GoogleAuthProvider.GetCredential(idToken, null);       
        // GoogleアカウントをAuthに紐付ける
        auth.SignInWithCredentialAsync(credencial).ContinueWith(authTask =>
        {
            if (authTask.IsCanceled)
            {
                Debug.Log($"LinkWithCredentialAsync Cancelled");
            }
            else if (authTask.IsFaulted)
            {
                Debug.Log($"LinkWithCredentialAsync Faulted");
            }
            else
            {
                Debug.Log($"LinkWithCredentialAsync Complete!");
            }
        });
    }

    // Androidから呼び出される。AndroidでGoogle Sign Inに失敗した事を教えてもらう
    public void GetIDTokenFailed(string errorCode)
    {
        Debug.Log($"GetIDTokenFromAndroid Failed!! {errorCode}");
    }
}

 

うまく処理が完了すると、FirebaseAuthとの連携が完了し、FirebaseのAuthenticationにGoogle Sign Inしたユーザーの情報が登録されます。

anonymousログインをしていて、anonymousをGoogleアカウントに切り替えたい場合は以下の部分を

auth.SignInWithCredentialAsync(credencial).ContinueWith(authTask =>

次に書き換えてください。anonymousのユーザーUIDのままプロバイダが匿名からGoogleに置き換わります。

auth.CurrentUser.LinkWithCredentialAsync(credencial).ContinueWith(task =>