Unity

【Unity】iOSネイティブ連携でGoogle Sign Inを実装する方法

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

しかし、最終更新日が5年ぐらい前で、最新のFirebaseライブラリーと組み合わせて使うと動きません。
また公式ライブラリは内部でWebViewを使っていますが、現在はWebViewの代わりにWKWebViewを使わないとAppleの審査が通らないので実質使えません。

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

 

Androidネイティブ連携でのGoogle Sign Inを行う方法はコチラ

【Unity】Androidネイティブ連携でGoogle Sign Inを実装する方法 Google Sign Inライブラリを使ったGoogle認証はdeprecatedとなり、Credential Manager...

 

Firebaseの用意

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

そして、Unity側で呼ぶFirebaseAuthとiOSネイティブのGoogle Sign Inを紐付けるための準備をしていきます。

 

Google Sign Inの有効化

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

設定ファイルの配置

全ての準備が完了したら、左上の歯車ボタンを押して、プロジェクトの設定を選び、googleServices-info.plistをダウンロードしたら、UnityプロジェクトのAssetsフォルダに配置します。

 

iOSネイティブでGoogle Sign In

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

Google Sign Inライブラリーの追加

コードを実装していく前に、エラーがでないようGoogle Sign Inライブラリーを最初に追加しておきます。

iOSフォルダ内にあるPodfileを開き、target ‘UnityFramework’ do から end の間に次の1行を追加します。

pod 'GoogleSignIn'

 

追加したら、ターミナルを開き、iOSフォルダ直下に移動して「pod update」コマンドを実行します。

 

SignIn.mmの実装

次にiOSネイティブ側でGoogle Sign Inを実行していくファイルを作成していきます。
Unity-iPhone/Libraries/Plugin/iOS フォルダの上で右クリックし「New File From Template…」メニューから「Objective-C File」を選択します。

ファイル名は「SignIn」としておきましょう。

保存先は、Assets/Plugins/iOS とします。
こうすることで、UnityでiOSビルドをするごとに自動でUnity-iPhone/Libraries/Plugin/iOS フォルダにSignInファイルがコピーされるようになり、Assets/Plugins以下をgitで管理していれば、iOSの環境を毎回復元できるようになります。

Objective-C++化

先ほど作成したSignIn.mファイルをXCode上で選択した状態でもう一回クリックすると拡張子が表示されるので、「.m」から「.mm」に変更します。

こうすることでObjective-CがObjective-C++になり、C++言語も使えるようになります。

 

Google Sign Inを実装

SignIn.mmファイルに次のGoogle Sing Inの実行コードを書きます。
このgoogleSignInメソッドをUnityから呼ぶことで、iOSネイティブ側でGoogle Sign Inが実行され、結果をUnityのTestControllerクラスに送る事ができるようになります。

#import <UnityFramework/UnityFramework.h>
#import "GoogleSignIn.h"

extern "C" void googleSignIn ()
{
    UnityAppController *appDelegate = (UnityAppController *)[UIApplication sharedApplication].delegate;
    UIViewController *currentViewController = appDelegate.window.rootViewController;
    if (currentViewController) {
        [GIDSignIn.sharedInstance
         signInWithPresentingViewController:currentViewController
            completion:^(GIDSignInResult * _Nullable signInResult, NSError * _Nullable error)
         {
            if (error) {
                UnitySendMessage([@"TestController" UTF8String], [@"GetIDTokenFailed" UTF8String], [[NSString stringWithFormat:@"%ld", error.code] UTF8String]);
            } else {
                if (signInResult.user.idToken != nil) {
                    UnitySendMessage([@"TestController" UTF8String], [@"GetIDToken" UTF8String], [signInResult.user.idToken.tokenString UTF8String]);
                } else {
                    UnitySendMessage([@"TestController" UTF8String], [@"GetIDTokenFailed" UTF8String], [@"" UTF8String]);
                }
            }
        }];
    } else {
        NSLog(@"ViewControllerを取得できませんでした。");
    }
}

 

info.plistの修正

次に、OAuth2でGoogle Sign InするためのクライアントID情報をInfo.plist (XCode上では拡張子無しのInfoと表示されています)に追加します。

しかし直接XCodeのファイルを書き換えても、iOSビルドで上書きされたり、iOSフォルダを削除してまるっと新しく作り直したなくなった時などに消えてしまうので、iOSビルドのタイミングで自動でInfoに追加されるよう次のPost Process処理を書いて、Assets/Editor/ios/Editorに配置しておきます。

これでiOSビルドをする時に毎回自動で追加されるので安心です。

YOUR_IOS_CLIENT_IDの部分には、FirebaseからダウンロードしたGoogleService-Info.plist内にある「CLIENT_ID」の値を、YOUR_DOT_REVERSED_IOS_CLIENT_IDの部分には、GoogleService-Info.plist内にある「REVERSED_CLIENT_ID」の値を入れてください。

using System.IO;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using UnityEngine;

namespace Hoge
{
    public class PostXcodeBuild
    {
        [PostProcessBuild]
        public static void SetXcodePlist(BuildTarget buildTarget, string pathToBuiltProject)
        {
            if (buildTarget != BuildTarget.iOS) return;

            var plistPath = pathToBuiltProject + "/Info.plist";
            var plist = new PlistDocument();
            plist.ReadFromString(File.ReadAllText(plistPath));

            /*
             * Google Sign In用の記述を追記
             */
            // GIDClientIDキーの追加
            plist.root.SetString("GIDClientID", "YOUR_IOS_CLIENT_ID");
            
            // CFBundleURLTypes配列の作成(既に存在する場合は取得)
            PlistElementArray urlTypes;
            if (plist.root.values.ContainsKey("CFBundleURLTypes"))
            {
                urlTypes = plist.root["CFBundleURLTypes"].AsArray();
            }
            else
            {
                urlTypes = plist.root.CreateArray("CFBundleURLTypes");
            }
            PlistElementDict urlDict = urlTypes.AddDict();
            PlistElementArray urlSchemes = urlDict.CreateArray("CFBundleURLSchemes");
            urlSchemes.AddString("YOUR_DOT_REVERSED_IOS_CLIENT_ID");

            
            // 変更内容をplistに反映
            File.WriteAllText(plistPath, plist.WriteToString());
 }

 

以上でiOSネイティブ側の実装は完成です。
試しに実機でiOSビルドを試して見てください。
問題なく起動するはずです。

 

 

Unity用FirebaseAuthと連携

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

FirebaseAuthパッケージの導入

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

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

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

C#の実装

iOSネイティブ側のSignIn.mmで、UnityのTestControllerのメソッドを呼び出すよう実装していたので、TestControllerファイルを作成します。

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

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

using UnityEngine;
using Firebase.Auth;
using Firebase.Extensions;
using System.Runtime.InteropServices;

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}");
            }
        });
    }

    [DllImport("__Internal", EntryPoint = "googleSignIn")]
    static extern void googleSignIn();

    // ネイティブに定義してあるメソッドを呼ぶ
    public void SignInWithGoogle()
    {
#if UNITY_IOS
        // iOSネイティブのメソッドを呼ぶ
        googleSignIn();

#elif UNITY_ANDROID
        // Androidネイティブのログインはこっちに
#else
        Debug.Log($"SignInWithGoogle error: unknown platform");
#endif
    }

    // ネイティブから呼び出される。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!");
            }
        });
    }

    // ネイティブから呼び出される。Google Sign Inに失敗した事を教えてもらう
    public void GetIDTokenFailed(string errorCode)
    {
        Debug.Log($"GetIDToken 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 =>