対象プラットフォーム:Android / iOS / Windows(デスクトップ)
UnityでFirebase Authentication使ってアカウント登録・ログイン機能を付ける方法を紹介します。SNSログイン対応してます。
1. 概要と設計方針(短め)
- 方針:クライアント(Unity)で各 SNS のネイティブログインを行い、取得したトークン(idToken / accessToken / identityToken)を Firebase の
SignInWithCredentialAsyncに渡して認証を完了する。 - メール/パスワードは Firebase の API を直接使う。SNS は各ネイティブ SDK を使う(GoogleSignIn, Facebook SDK, Sign in with Apple プラグイン)。
- Windows(デスクトップ)は Firebase Unity SDK の機能制限があるため、必要なら REST API を用いた代替案を用意する。
- アカウントの衝突(同じメールで別プロバイダ)時は
FetchSignInMethodsForEmailAsyncとLinkWithCredentialAsyncでリンクして UX を整える。
2. 必要な準備(Firebase コンソール、ダウンロード物、Unity 設定)
- Firebase コンソールでやること(全プラットフォーム)
- Unity プロジェクト側(準備)
- FirebaseAuthManager.cs
- EmailAuth.cs(メール登録・ログイン・パスワードリセット)
- GoogleAuthHandler.cs(Google Sign-In → Firebase)
- FacebookAuthHandler.cs(Facebook SDK → Firebase)
- AppleAuthHandler.cs(Sign in with Apple → Firebase)
- AuthUIController.cs(UI とバリデーションの例)
- ProfileService.cs(ユーザープロフィール保存の例:Firestore を仮定)
- AuthErrorHandler.cs(エラー解析)
- Utils.cs(nonce / SHA256 / keyhash helper)
- Firebase Unity SDK
- Google Sign-In
- Facebook SDK
- Sign in with Apple
- 7.1 キーストア生成(開発用)
- 7.2 SHA-1 / SHA-256 取得
- 7.3 google-services.json の配置
- 7.4 AndroidManifest / ProGuard
- 7.5 Play App Signing(公開時)
- 8.1 GoogleService-Info.plist の配置
- 8.2 URL Scheme(REVERSED_CLIENT_ID)
- 8.3 Sign in with Apple(Capability)
- 8.4 Other Linker Flags / Frameworks
- 9.1 オプション A:エディタ/Windows は「テスト専用」にする
- 9.2 オプション B:REST API を使う(Windows 実運用する場合)
- 共通の確認ポイント
- よくあるエラーと対策(抜粋)
- ログ取り
Firebase コンソールでやること(全プラットフォーム)
- Firebase プロジェクトを作成。
- Authentication → Sign-in method で以下を有効化:
- Email/Password
- Apple(iOS 用)
- Android/iOS アプリをそれぞれ追加して、
google-services.json(Android)とGoogleService-Info.plist(iOS)をダウンロードする。これらは後で Unity のAssets/配下に置きます。
重要:Android は
SHA-1/SHA-256を Firebase に登録する必要があります(開発用 keystore / リリース keystore / Play App Signing の署名など)。Facebook は Android の Key Hash、iOS は Apple Developer で Sign in with Apple を有効にする必要があります。これらは後述します。
Unity プロジェクト側(準備)
- Unity 推奨バージョン:2020 LTS 以降(推奨は 2021.3 LTS など)。ただし Firebase のサポート範囲を確認して使ってください。
- 新規プロジェクトを作成(3D または URP/Universal などお好みで)。
Assets/Plugins/フォルダを用意してプラグインを格納すると管理しやすい。Player Settings:package name(Bundle Identifier)を Firebase コンソールで登録したものと一致させる。Android/iOS で別々の ID を使う場合はそれぞれ登録済みであること。
3. 推奨プロジェクト構成(例)
Assets/
Scripts/
Auth/
FirebaseAuthManager.cs
EmailAuth.cs
GoogleAuthHandler.cs
FacebookAuthHandler.cs
AppleAuthHandler.cs
AuthUIController.cs
ProfileService.cs
AuthErrorHandler.cs
Utils.cs
Plugins/
Firebase/ <- Firebase SDK をここに
GoogleSignIn/
FacebookSDK/
AppleSignIn/
Scenes/
AuthScene.unity
MainScene.unity
Resources/
Prefabs/
AuthUI.prefab
4. フルコード(Unity C# スクリプト一式)
使い方:以下のファイルを
Assets/Scripts/Auth/に配置してください。コメントで使い方を併記しています。各ハンドラはプラットフォームコンパイル定義(#if UNITY_ANDROID等)を使っており、エディタではダミー挙動を返すようにしています(テストのため)。
FirebaseAuthManager.cs
// FirebaseAuthManager.cs
using System;
using UnityEngine;
using Firebase;
using Firebase.Auth;
using System.Threading.Tasks;
public class FirebaseAuthManager : MonoBehaviour
{
public static FirebaseAuthManager Instance { get; private set; }
public FirebaseAuth Auth { get; private set; }
public FirebaseUser CurrentUser => Auth?.CurrentUser;
void Awake()
{
if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); }
else { Destroy(gameObject); return; }
InitializeFirebase();
}
void InitializeFirebase()
{
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
var status = task.Result;
if (status == DependencyStatus.Available)
{
Auth = FirebaseAuth.DefaultInstance;
Debug.Log("[FirebaseAuthManager] Firebase initialized. CurrentUser: " + (Auth.CurrentUser != null ? Auth.CurrentUser.Email : "none"));
}
else
{
Debug.LogError("[FirebaseAuthManager] Could not resolve all Firebase dependencies: " + status);
}
});
}
// サインアウト(全プロバイダ用)
public void SignOut()
{
if (Auth != null) Auth.SignOut();
Debug.Log("[FirebaseAuthManager] Signed out local user.");
}
// カスタムトークンでのサインイン(サーバーで作成したトークンを使う場合)
public void SignInWithCustomToken(string token)
{
Auth.SignInWithCustomTokenAsync(token).ContinueWith(t =>
{
if (t.IsFaulted) Debug.LogError("[FirebaseAuthManager] SignInWithCustomToken failed: " + t.Exception);
else Debug.Log("[FirebaseAuthManager] Signed in with custom token: " + t.Result.Email);
});
}
}
EmailAuth.cs(メール登録・ログイン・パスワードリセット)
// EmailAuth.cs
using System;
using UnityEngine;
using Firebase.Auth;
public class EmailAuth : MonoBehaviour
{
FirebaseAuth auth => FirebaseAuthManager.Instance.Auth;
public void Register(string email, string password, Action<FirebaseUser, string> callback)
{
auth.CreateUserWithEmailAndPasswordAsync(email, password).ContinueWith(task =>
{
if (task.IsCanceled || task.IsFaulted)
{
var msg = AuthErrorHandler.FormatAggregateException(task.Exception);
Debug.LogError("[EmailAuth] Register failed: " + msg);
callback?.Invoke(null, msg);
return;
}
var newUser = task.Result;
Debug.Log("[EmailAuth] Registered: " + newUser.Email);
callback?.Invoke(newUser, null);
});
}
public void Login(string email, string password, Action<FirebaseUser, string> callback)
{
auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task =>
{
if (task.IsCanceled || task.IsFaulted)
{
var msg = AuthErrorHandler.FormatAggregateException(task.Exception);
Debug.LogError("[EmailAuth] Login failed: " + msg);
callback?.Invoke(null, msg);
return;
}
var user = task.Result;
Debug.Log("[EmailAuth] Logged in: " + user.Email);
callback?.Invoke(user, null);
});
}
public void SendPasswordReset(string email, Action<string> callback)
{
auth.SendPasswordResetEmailAsync(email).ContinueWith(task =>
{
if (task.IsFaulted)
{
var msg = AuthErrorHandler.FormatAggregateException(task.Exception);
Debug.LogError("[EmailAuth] PasswordReset failed: " + msg);
callback?.Invoke(msg);
return;
}
Debug.Log("[EmailAuth] Password reset email sent.");
callback?.Invoke(null);
});
}
}
GoogleAuthHandler.cs(Google Sign-In → Firebase)
注:このファイルは Google Sign-In プラグイン(またはネイティブラッパー)を使う前提のコード例です。プラグインの API に合わせて
SignInWithGoogleNative()部分を実装してください。エディタ時・Windows はテスト用のダミー処理があります。
// GoogleAuthHandler.cs
using UnityEngine;
using Firebase.Auth;
using System;
public class GoogleAuthHandler : MonoBehaviour
{
FirebaseAuth auth => FirebaseAuthManager.Instance.Auth;
// プラグイン固有の SignIn 呼び出しをここに書く
public void SignInWithGoogle(Action<FirebaseUser, string> callback)
{
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
// エディタ/Windows デバッグ用: ダミーアカウントの作成(開発時のみ)
Debug.Log("[GoogleAuthHandler] Editor/Windows dummy google sign-in.");
// ここは実際にはトークンを取得できないため、テスト用の匿名ログインなどにする
auth.SignInAnonymouslyAsync().ContinueWith(t => {
if (t.IsFaulted) callback?.Invoke(null, AuthErrorHandler.FormatAggregateException(t.Exception));
else callback?.Invoke(t.Result, null);
});
#else
// 実機: Google Sign-In プラグインを起動
SignInWithGoogleNative((idToken, accessToken, error) =>
{
if (!string.IsNullOrEmpty(error))
{
callback?.Invoke(null, error);
return;
}
var credential = GoogleAuthProvider.GetCredential(idToken, accessToken);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsFaulted || task.IsCanceled)
{
var msg = AuthErrorHandler.FormatAggregateException(task.Exception);
Debug.LogError("[GoogleAuthHandler] Firebase sign-in failed: " + msg);
callback?.Invoke(null, msg);
return;
}
var user = task.Result;
Debug.Log("[GoogleAuthHandler] Signed in with Google: " + user.Email);
callback?.Invoke(user, null);
});
});
#endif
}
// ここをプラグイン API に合わせて実装してください
private void SignInWithGoogleNative(Action<string, string, string> cb)
{
// idToken, accessToken, error
// 例: GoogleSignIn.DefaultInstance.SignIn() の結果から idToken を cb に渡す
cb?.Invoke(null, null, "Not implemented: Replace SignInWithGoogleNative with plugin call.");
}
}
FacebookAuthHandler.cs(Facebook SDK → Firebase)
// FacebookAuthHandler.cs
using UnityEngine;
using Firebase.Auth;
using System;
using System.Collections.Generic;
#if FACEBOOK_SDK
using Facebook.Unity;
#endif
public class FacebookAuthHandler : MonoBehaviour
{
FirebaseAuth auth => FirebaseAuthManager.Instance.Auth;
public void LoginWithFacebook(Action<FirebaseUser, string> callback)
{
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
// Editor/Windows fallback
Debug.Log("[FacebookAuthHandler] Editor/Windows: falling back to anonymous login.");
auth.SignInAnonymouslyAsync().ContinueWith(t =>
{
if (t.IsFaulted) callback?.Invoke(null, AuthErrorHandler.FormatAggregateException(t.Exception));
else callback?.Invoke(t.Result, null);
});
#else
#if FACEBOOK_SDK
if (!FB.IsInitialized)
{
FB.Init(() => {
FB.ActivateApp();
ContinueFBLogin(callback);
});
return;
}
ContinueFBLogin(callback);
#else
callback?.Invoke(null, "Facebook SDK not imported. Define FACEBOOK_SDK and install Facebook Unity SDK.");
#endif
#endif
}
#if FACEBOOK_SDK
void ContinueFBLogin(Action<FirebaseUser, string> callback)
{
var perms = new List<string>() { "public_profile", "email" };
FB.LogInWithReadPermissions(perms, result =>
{
if (result == null || !FB.IsLoggedIn)
{
callback?.Invoke(null, "Facebook login cancelled or failed.");
return;
}
string accessToken = AccessToken.CurrentAccessToken.TokenString;
var credential = FacebookAuthProvider.GetCredential(accessToken);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsFaulted) callback?.Invoke(null, AuthErrorHandler.FormatAggregateException(task.Exception));
else callback?.Invoke(task.Result, null);
});
});
}
#endif
}
AppleAuthHandler.cs(Sign in with Apple → Firebase)
重要:iOS(実機)で Sign in with Apple を使う場合は Unity 用の Apple SignIn プラグインを導入するのが現実的です。ここでは nonce 生成と Firebase への渡し方を示します。プラグイン API に合わせて
SignInWithAppleNative()を実装してください。
// AppleAuthHandler.cs
using System;
using UnityEngine;
using Firebase.Auth;
public class AppleAuthHandler : MonoBehaviour
{
FirebaseAuth auth => FirebaseAuthManager.Instance.Auth;
public void SignInWithApple(Action<FirebaseUser, string> callback)
{
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
// Editor/Windows: fallback
Debug.Log("[AppleAuthHandler] Editor/Windows fallback to anonymous.");
auth.SignInAnonymouslyAsync().ContinueWith(t =>
{
if (t.IsFaulted) callback?.Invoke(null, AuthErrorHandler.FormatAggregateException(t.Exception));
else callback?.Invoke(t.Result, null);
});
#else
// iOS 実機: nonce を作ってネイティブプラグインに渡す
string rawNonce = Utils.GenerateNonce();
string hashed = Utils.Sha256(rawNonce);
SignInWithAppleNative(hashed, (identityToken, error) =>
{
if (!string.IsNullOrEmpty(error))
{
callback?.Invoke(null, error);
return;
}
// identityToken と rawNonce(ハッシュではなく**生の**rawNonce)を Firebase に渡す
var credential = OAuthProvider.GetCredential("apple.com", identityToken, rawNonce);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsFaulted) callback?.Invoke(null, AuthErrorHandler.FormatAggregateException(task.Exception));
else callback?.Invoke(task.Result, null);
});
});
#endif
}
// プラグインの呼び出しに合わせて実装
void SignInWithAppleNative(string hashedNonce, Action<string, string> cb)
{
cb?.Invoke(null, "Not implemented: replace with Sign in with Apple plugin call.");
}
}
AuthUIController.cs(UI とバリデーションの例)
// AuthUIController.cs
using UnityEngine;
using UnityEngine.UI;
using System;
public class AuthUIController : MonoBehaviour
{
[Header("Email")]
public InputField emailInput;
public InputField passwordInput;
public Button emailRegisterButton;
public Button emailLoginButton;
[Header("Social")]
public Button googleButton;
public Button facebookButton;
public Button appleButton;
[Header("Status")]
public Text statusText;
EmailAuth emailAuth;
GoogleAuthHandler googleAuth;
FacebookAuthHandler facebookAuth;
AppleAuthHandler appleAuth;
void Awake()
{
emailAuth = GetComponent<EmailAuth>() ?? gameObject.AddComponent<EmailAuth>();
googleAuth = GetComponent<GoogleAuthHandler>() ?? gameObject.AddComponent<GoogleAuthHandler>();
facebookAuth = GetComponent<FacebookAuthHandler>() ?? gameObject.AddComponent<FacebookAuthHandler>();
appleAuth = GetComponent<AppleAuthHandler>() ?? gameObject.AddComponent<AppleAuthHandler>();
emailRegisterButton.onClick.AddListener(() => OnRegisterClicked());
emailLoginButton.onClick.AddListener(() => OnLoginClicked());
googleButton.onClick.AddListener(() => OnGoogleClicked());
facebookButton.onClick.AddListener(() => OnFacebookClicked());
appleButton.onClick.AddListener(() => OnAppleClicked());
}
void SetStatus(string s) { statusText.text = s; Debug.Log("[AuthUI] " + s); }
void OnRegisterClicked()
{
var email = emailInput.text.Trim();
var password = passwordInput.text;
var err = ValidateEmailPassword(email, password);
if (err != null) { SetStatus(err); return; }
SetStatus("Registering...");
emailAuth.Register(email, password, (user, error) => {
UnityMainThreadDispatcher.Instance().Enqueue(() => {
if (!string.IsNullOrEmpty(error)) SetStatus("Register error: " + error);
else SetStatus("Registered: " + user.Email);
});
});
}
void OnLoginClicked()
{
var email = emailInput.text.Trim();
var password = passwordInput.text;
var err = ValidateEmailPassword(email, password);
if (err != null) { SetStatus(err); return; }
SetStatus("Signing in...");
emailAuth.Login(email, password, (user, error) => {
UnityMainThreadDispatcher.Instance().Enqueue(() => {
if (!string.IsNullOrEmpty(error)) SetStatus("Login error: " + error);
else SetStatus("Signed in: " + user.Email);
});
});
}
void OnGoogleClicked()
{
SetStatus("Google sign-in...");
googleAuth.SignInWithGoogle((user, error) => {
UnityMainThreadDispatcher.Instance().Enqueue(() => {
if (!string.IsNullOrEmpty(error)) SetStatus("Google error: " + error);
else SetStatus("Google signed in: " + user.Email);
});
});
}
void OnFacebookClicked()
{
SetStatus("Facebook sign-in...");
facebookAuth.LoginWithFacebook((user, error) => {
UnityMainThreadDispatcher.Instance().Enqueue(() => {
if (!string.IsNullOrEmpty(error)) SetStatus("Facebook error: " + error);
else SetStatus("Facebook signed in: " + user.Email);
});
});
}
void OnAppleClicked()
{
SetStatus("Apple sign-in...");
appleAuth.SignInWithApple((user, error) => {
UnityMainThreadDispatcher.Instance().Enqueue(() => {
if (!string.IsNullOrEmpty(error)) SetStatus("Apple error: " + error);
else SetStatus("Apple signed in: " + user.Email);
});
});
}
string ValidateEmailPassword(string email, string password)
{
if (string.IsNullOrEmpty(email) || !email.Contains("@")) return "Invalid email.";
if (string.IsNullOrEmpty(password) || password.Length < 6) return "Password must be 6+ chars.";
return null;
}
}
注:
UnityMainThreadDispatcherは非同期コールバックを UI スレッドで実行するための簡易ユーティリティです。Asset Store 等で入手するか簡易実装を用意してください(付録参照)。
ProfileService.cs(ユーザープロフィール保存の例:Firestore を仮定)
// ProfileService.cs
using UnityEngine;
using Firebase.Firestore;
using System.Threading.Tasks;
public class ProfileService : MonoBehaviour
{
FirebaseFirestore db => FirebaseFirestore.DefaultInstance;
public async Task SaveProfileAsync(string uid, string email, string displayName = null, string photoUrl = null)
{
var doc = new DocumentReference(db, $"users/{uid}");
var data = new System.Collections.Generic.Dictionary<string, object>
{
{ "email", email },
{ "displayName", displayName ?? "" },
{ "photoUrl", photoUrl ?? "" },
{ "updatedAt", Timestamp.GetCurrentTimestamp() }
};
await doc.SetAsync(data, SetOptions.MergeAll);
Debug.Log("[ProfileService] Profile saved for: " + uid);
}
}
AuthErrorHandler.cs(エラー解析)
// AuthErrorHandler.cs
using System;
using Firebase;
using Firebase.Auth;
using System.Linq;
public static class AuthErrorHandler
{
public static string FormatAggregateException(AggregateException agg)
{
if (agg == null) return "Unknown error";
var flat = agg.Flatten();
var inner = flat.InnerExceptions.FirstOrDefault();
if (inner is FirebaseException fex)
{
return $"Firebase Error ({fex.ErrorCode}): {fex.Message}";
}
return inner?.Message ?? agg.Message;
}
}
Utils.cs(nonce / SHA256 / keyhash helper)
// Utils.cs
using System;
using System.Security.Cryptography;
using System.Text;
public static class Utils
{
private const string CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
public static string GenerateNonce(int length = 32)
{
var sb = new StringBuilder();
using (var rng = RandomNumberGenerator.Create())
{
var buf = new byte[1];
for (int i = 0; i < length; i++)
{
rng.GetBytes(buf);
sb.Append(CHARSET[buf[0] % CHARSET.Length]);
}
}
return sb.ToString();
}
public static string Sha256(string input)
{
using (var sha = SHA256.Create())
{
var bytes = Encoding.UTF8.GetBytes(input);
var hash = sha.ComputeHash(bytes);
var sb = new StringBuilder();
foreach (var b in hash) sb.AppendFormat("{0:x2}", b);
return sb.ToString();
}
}
}
5. Unity シーン & UI の作り方(スクリーン構成)
- シーン名:
AuthScene.unity - Canvas:
AuthCanvas(画面中央にログイン UI)- InputField:
EmailInput(プレースホルダ “Email”) - InputField:
PasswordInput(Input Type = Password) - Button:
RegisterButton(ラベル “Register”) - Button:
LoginButton(ラベル “Login”) - Button:
GoogleButton(ラベル “Google サインイン”) - Button:
FacebookButton(ラベル “Facebook ログイン”) - Button:
AppleButton(ラベル “Sign in with Apple” — iOS のみ) - Text:
StatusText(ログ出力表示用)
- InputField:
AuthUIControllerを Canvas にアタッチし、各フィールドを紐づける。FirebaseAuthManagerを別 GameObject(例:FirebaseManager)としてシーンに追加しておく(DontDestroyOnLoadによりアプリ起動から常駐)。
6. プラグイン導入手順(概要)
Firebase Unity SDK
- Firebase の公式ページから Unity SDK をダウンロード。
FirebaseAuth.unitypackage/FirebaseFirestore.unitypackage等、必要なパッケージを Unity にインポート。Assets/Plugins/Android/Assets/Plugins/iOSを生成して SDK のファイルが配置されるのを確認。- External Dependency Manager(Play Services Resolver)が入っていることを確認し、依存解決を実行(メニューから
Assets > External Dependency Manager > Android Resolver > Resolve)。
Google Sign-In
- Android/iOS 向けに Google Sign-In プラグインを導入(GoogleSignIn Unity plugin や、Google Play Games plugin など)。プラグインにより API が異なるため、
GoogleAuthHandler.SignInWithGoogleNativeをプラグインの呼び出しに書き換える。
Facebook SDK
- Facebook for Unity SDK をダウンロードしてインポート。インポート後
FB.Init()が使えるようになります。FacebookAuthHandler内に#if FACEBOOK_SDKを入れておくと便利(定義はScripting Define Symbolsに追加)。
Sign in with Apple
- Unity 用 Sign in with Apple プラグイン(Asset Store や GitHub)を導入。プラグインの API に合わせて
AppleAuthHandler.SignInWithAppleNativeを実装。iOS 側で capability を有効にする必要あり。
各プラグインはバージョン差やセットアップ手順があるため、必ず公式 README を確認してください。プラグイン導入後に Android の Gradle / iOS の Xcode プロジェクトが自動で編集されます。
7. Android ビルド手順(キーストア、SHA登録、Gradle 設定)
7.1 キーストア生成(開発用)
keytool -genkey -v -keystore debug.keystore -alias mykey -keyalg RSA -keysize 2048 -validity 10000
(Unity の Player Settings > Publishing Settings で keystore を管理することを推奨します。開発用は ~/.android/debug.keystore を使うことが多い。)
7.2 SHA-1 / SHA-256 取得
# Windows
keytool -list -v -keystore <path-to-keystore> -alias <alias> -storepass <password>
# macOS / Linux 同様
keytool の出力に SHA1 と SHA256 が出るので、Firebase コンソールの Android アプリ設定で追加してください(開発用・リリース用・Play App Signing の署名をそれぞれ登録)。
7.3 google-services.json の配置
ダウンロードした google-services.json を Assets に置く(通常は Assets/Plugins/Android に置かれても OK)。Unity の Android Resolver が Gradle に自動で反映します。
7.4 AndroidManifest / ProGuard
- Facebook SDK や GoogleSignIn が必要とする権限や activity を
AndroidManifestに追加する必要があります。プラグインが生成する場合が多いですが、手動で追加する場合はAssets/Plugins/Android/AndroidManifest.xmlを作って統合してください。 - ProGuard を使う場合は SDK のドキュメントに従った例外ルールを追加。
7.5 Play App Signing(公開時)
- Google Play にアップロードする場合、Play App Signing の署名が本番で使われます。Play Console が保持する署名の SHA を Firebase に登録しないと Google ログインが本番で失敗することがあります。必ず Play Console で署名を確認し、Firebase に登録してください。
8. iOS ビルド手順(plist、URL Scheme、Xcode 設定、Capabilities)
8.1 GoogleService-Info.plist の配置
GoogleService-Info.plistをAssets/に置くと、Unity の iOS ビルドで自動的に Xcode プロジェクトに含まれます。ビルド後に Xcode 側で plist が存在するか確認してください。
8.2 URL Scheme(REVERSED_CLIENT_ID)
GoogleService-Info.plistに含まれるREVERSED_CLIENT_IDを Xcode のInfo→URL Typesに自動で追加するか、手動で設定してください。これがないと Google Sign-In が動作しません。
8.3 Sign in with Apple(Capability)
- Xcode の Targets → Signing & Capabilities →
+ Capabilityから Sign In with Apple を追加。Apple Developer にて App ID のSign in with Appleを有効にしておく必要があります。
8.4 Other Linker Flags / Frameworks
- プラグインに従って
Other Linker Flagsや必要な frameworks(AuthenticationServices など)を追加してください。
9. Windows(デスクトップ)での運用方法(制約と REST API フォールバック)
Unity エディタや Windows スタンドアロンで動かす際、Firebase Unity SDK の一部機能が制限されることがあります。特に SNS のネイティブ SDK はモバイル向けのためそのまま動かないケースが多いです。
9.1 オプション A:エディタ/Windows は「テスト専用」にする
- 開発中は Editor で匿名ログインやメールログインで動作確認、SNS は実機で検証する。
9.2 オプション B:REST API を使う(Windows 実運用する場合)
Firebase の Auth は REST API を提供しているので、Windows クライアントから REST で認証(メール/パスワード、カスタムトークン)を実装できます。SNS の OAuth はクライアントで行い、トークンをサーバー経由で Firebase に紐付ける(セキュア)方法が現実的です。
例:メール/パスワード via REST
POST https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=[API_KEY]
Body JSON:
{
"email": "user@example.com",
"password": "password",
"returnSecureToken": true
}
戻り値に idToken が返る。クライアントはこの idToken をサーバーへ送って検証するか、セッションとして扱います。
REST 経由の実装はセキュリティ設計(API キー管理・TLS・CORS 等)を慎重に行ってください。特に API キーはクライアントから見えるため、重要操作はサーバー側で検証することをおすすめします。
10. サーバー側ワークフロー(Node.js でのカスタムトークン生成例)
OAuth を自前サーバーで検証して Firebase カスタムトークンを発行したい場合(例:デスクトップで OAuth を行い安全に Firebase にサインインさせたい)に使えます。
Node.js(firebase-admin)でのカスタムトークン発行例
// server.js(Node.js)
const admin = require('firebase-admin');
const serviceAccount = require('./serviceAccountKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
// 任意の uid(例:Google の sub)でカスタムトークン発行
app.post('/createCustomToken', async (req, res) => {
const { uid } = req.body;
try {
const token = await admin.auth().createCustomToken(uid);
res.json({ token });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
クライアントはこの token を受け取り FirebaseAuthManager.SignInWithCustomToken(token) でサインインできます。
サーバー側で OAuth トークン(Google / Facebook / Apple のトークン)を検証してから Firebase Admin で
createCustomToken()を行えば、デスクトップクライアントでも安全に Firebase ユーザーを作成できます。
11. テスト & デバッグ術(ログ・よくあるエラー対処)
共通の確認ポイント
- Firebase の
google-services.json/GoogleService-Info.plistが正しいアプリに紐づいているか。 - Android の
package name/ iOS のBundle IDと Firebase に登録した値が一致しているか。 - Android の SHA-1 が Firebase に登録されているか(特に Google ログイン)。
- Facebook の Key Hash(Android)を Facebook Developers コンソールに登録しているか。
- Sign in with Apple は Apple Developer と Xcode 側の Capability が一致しているか。
よくあるエラーと対策(抜粋)
invalid client/DEVELOPER_ERROR(Google Sign-In) → SHA-1 / OAuth クライアントの設定が間違い。Invalid key hash(Facebook) → Key Hash が正しく登録されていない(デバッグキー / リリースキーの差)。AccountExistsWithDifferentCredential→ 同じメールで別プロバイダのアカウントが存在。FetchSignInMethodsForEmailAsyncで手順を説明してリンク。identityToken/nonce関連エラー(Apple) → rawNonce の SHA256 を Apple 側に渡し、返却される identityToken と rawNonce 生値を Firebase に渡すこと。
ログ取り
- Android:
adb logcatでFirebaseAuth/Unityのログを監視。 - iOS:Xcode のコンソールでログ確認。
- Unity Editor:
ConsoleとDebug.Log、UnityMainThreadDispatcherを使って UI 更新時のログを管理。
12. リリース前チェックリスト(最終確認)
共通
- Firebase の Authentication > Sign-in method で使う方法が有効化済みか。
- 全プラットフォームで
google-services.json/GoogleService-Info.plistを正しく配置しているか。 - アプリのプライバシーポリシーを用意し、必要な権限と用途を記載しているか(Facebook, Apple のポリシー対応)。
Android
- 開発用・リリース用 keystore の SHA-1 / SHA-256 を Firebase に登録。
- Facebook の Key Hash を登録。
- ProGuard/Minify を使うなら必要な keep 設定を追加。
- Play App Signing を使う場合は Play Console の署名 SHA を Firebase に登録。
iOS
- Xcode の
Signing & Capabilitiesが正しく設定されているか(Team, Provisioning Profile)。 - Sign in with Apple を利用する場合は App ID に機能を追加し、Xcode の Capability をオンにしているか。
GoogleService-Info.plistと URL Scheme が正しく Xcode に含まれているか。
Windows
- デスクトップで Firebase の機能制限を想定しているか(REST / カスタムトークンでの補完)。
- API キー・サーバー側の検証フローを整備しているか(重要操作はサーバーで検証)。
13. 付録:重要コマンド一覧(keytool / openssl / adb)
SHA-1 / SHA-256 の取得(debug keystore 例)
# Windows / macOS / Linux
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
Facebook Key Hash の生成(例)
# Windows / macOS
keytool -exportcert -alias <alias> -keystore <keystore> | openssl sha1 -binary | openssl base64
(<keystore> に debug.keystore などを指定。openssl が必要)
adb logcat(Android ログ)
adb logcat -s Unity ActivityManager FirebaseAuth Firebase
# または全ログ: adb logcat
14. 最後に(まとめ)
ここまでで、メール認証 + Google / Facebook / Apple を Unity で扱うためのフルコードと、Android / iOS / Windows 各プラットフォームのビルド手順・注意点・デバッグ法・サーバー側補完の方法まで網羅しました。実務でハマるポイント(SHA / Key Hash / nonce / Play App Signing 等)を重点的に扱っています。
