以前開発したときはParseをUnityのサーバサイドとして使ってましたがサービス終了してしまったので、Firebaseを導入します。FirebaseはAnalyticsや匿名のユーザ認証など多くの機能がついています。個人的にはクライアントのイベントログをFirebaseに送って、それをリアルタイムにBigQueryにシンクできるところが気に入ってます。
必須環境
Adding Firebase to your Unity Projectを参考にします。記事を書いている時点では以下でした。
- iOS
- Unity 5.3以上
- Xcode 7.0以上
- CocoaPods 1.0.0 or later
- Android
- Unity 5.3以上
- Android 2.3 (Gingerbread)以上
導入環境
- Unity: 5.5.1f1
- Xcode: 8.2.1
- Firebase:
- 導入端末
- iOS: 10.2.1
なお、CocoaPodsが必要なので以下でいれておきます
sudo gem install -n /usr/local/bin cocoapods
導入方法
Firebaseプロジェクトの作成
Adding Firebase to your Unity Projectに手順がいろいろ書いてあるので、設定します。iOSとAndroidのアプリもFirebase Consoleで追加しておきます。
Firebase Unity SDK
Adding Firebase to your Unity ProjectのDownload the sdkをクリックしてSDKを入手します。
解凍すると以下のようなパッケージがあります。
Feature | Unity Package |
---|---|
Firebase Analytics | FirebaseAnalytics.unitypackage |
Firebase Authentication | FirebaseAuth.unitypackage |
Firebase Realtime Database | FirebaseDatabase.unitypackage |
Firebase Invites and Dynamic Links | FirebaseInvites.unitypackage |
Firebase Messaging | FirebaseMessaging.unitypackage |
Firebase Realtime Database | FirebaseDatabase.unitypackage |
Firebase Remote Config | FirebaseRemoteConfig.unitypackage |
Firebase Storage | FirebaseStorage.unitypackage |
Remote Config (Unity用ドキュメント)
今回は強制アップデートの仕組みをRemote Configで実現しようと思います。
強制アップデートとは、クライアントのバージョンがFirebase側で指定しているバージョンより低かったらストアに飛ばすようにすることです。
最初に、Firebase Console側のRemote Configのminimum_version
を以下のように設定します。
Unityでのアプリバージョンは以下のよう設定します。
次に、目的のプロジェクトを開いてから、先程解凍したファイルのFirebaseRemoteConfig.unitypackage
を開きます。各種インポートしたら、FirebaseのConsoleでiOSアプリを追加した際にダウンロードされたGoogleService-Info.plist
とgoogle-services.json
をUnityプロジェクトの任意の場所に配置します。今回は以下のようにしました。
C#のコードでfetchは以下のようにします。
using System.Threading.Tasks;
// 強制アップデート用
void CheckVersion ()
{
if (Debug.isDebugBuild) {
// FirebaseはRemoteConfigの値はキャッシュする. Debug modeだとキャッシュしなくなる
Debug.Log ("debug mode version check");
var settings = Firebase.RemoteConfig.FirebaseRemoteConfig.Settings;
settings.IsDeveloperMode = true;
Firebase.RemoteConfig.FirebaseRemoteConfig.Settings = settings;
}
Task fetchTask = Firebase.RemoteConfig.FirebaseRemoteConfig.FetchAsync (new TimeSpan (0));
fetchTask.ContinueWith (VersionFetchComplete);
}
void VersionFetchComplete (Task fetchTask)
{
if (fetchTask.IsCanceled) {
Debug.Log ("Fetch canceled.");
} else if (fetchTask.IsFaulted) {
Debug.Log ("Fetch encountered an error.");
} else if (fetchTask.IsCompleted) {
Debug.Log ("Fetch completed successfully!");
}
switch (Firebase.RemoteConfig.FirebaseRemoteConfig.Info.LastFetchStatus) {
case Firebase.RemoteConfig.LastFetchStatus.Success:
// 正しくフェッチできたときだけバージョンチェックをする.
Debug.Log ("Remote data loaded and ready.");
Firebase.RemoteConfig.FirebaseRemoteConfig.ActivateFetched ();
var minimumVersion = Firebase.RemoteConfig.FirebaseRemoteConfig.GetValue ("minimum_version").StringValue;
#if UNITY_EDITOR
// 注意: EditorではIsDeveloperModeがtrueに設定できないため動作確認できないので実機で確認すること
minimumVersion = "1.0.0"; // Debug用
#endif
if (NeedUpdate (Application.version, minimumVersion)) {
Debug.Log ("need to update");
} else {
Debug.Log ("no need to update");
}
break;
case Firebase.RemoteConfig.LastFetchStatus.Failure:
switch (Firebase.RemoteConfig.FirebaseRemoteConfig.Info.LastFetchFailureReason) {
case Firebase.RemoteConfig.FetchFailureReason.Error:
Debug.Log ("Fetch failed for unknown reason");
break;
case Firebase.RemoteConfig.FetchFailureReason.Throttled:
Debug.Log ("Fetch throttled until " +
Firebase.RemoteConfig.FirebaseRemoteConfig.Info.ThrottledEndTime);
break;
}
break;
case Firebase.RemoteConfig.LastFetchStatus.Pending:
Debug.Log ("Latest Fetch call still pending.");
break;
}
}
bool NeedUpdate (string currentVersion, string minimumVersion)
{
int[] currentVersions = Array.ConvertAll (currentVersion.Split ('.'), int.Parse);
int[] minimumVersions = Array.ConvertAll (minimumVersion.Split ('.'), int.Parse);
for (var i = 0; i < minimumVersions.Length; i++) {
if (currentVersions [i] < minimumVersions [i]) {
return true;
}
}
return false;
}
注意点としてRemote Configはデフォルトで12時間、値をローカルにキャッシュします。これに気づいてなくて、Firebase ConsoleからRemote Configの値をかえたのに、実機では値がかわらなくてハマってました(参考)。このキャッシュの期限はFetchAsync時に設定できます。
Developer Modeにするとキャッシュしないで常に最新の値がとれます。Developer ModeにするにはFirebase.RemoteConfig.FirebaseRemoteConfig.Settings.IsDeveloperMode = true;
で設定できます。ただし、Unity Editor内ではFirebaseのRemoteConfigは正しく動かないのと、IsDeveloperModeがTrueにならないので注意する必要があります。さきほどのコードではDebug Buildの時のみtrueにしています。
ちなみにDebug.isDebugBuild
は以下のようにDeveloper Modeにチェックを入れるとtrueになります。
今回は、デバッグログを出しただけでしたが、Nativeのダイアログを開きたい場合はMobile Native PopUpsのアセットを使えば簡単にNativeのポップアップが出せます。自分がやったときはISN_NativeCore.h
とISN_NativeCore.mm
がデフォルトでただしくXcodeで読み込まれなかったのでその際は手動で、Plugins/iOSの下に移動させ、.txtファイルになっていたのでtxtの拡張子を取り除いたところ正常に動作しました。
Analytics (Unity用ドキュメント]
Unityで該当のプロジェクトを開きながら、FirebaseAnalytics.unitypackage
を開きインポートします。
以下のようなコードでイベントを送れます。
// イベントのみ送りたいとき
FirebaseAnalytics.LogEvent ("l_purchase_finish");
// パラメータをつけて送りたいとき
FirebaseAnalytics.LogEvent (
"l_start_stage",
new [] {
new Parameter ("level", level),
new Parameter ("stage", stage),
}
);
iOSでイベントをデバッグ
デバッグ時はリアルタイムでAnalyticsイベントデータを監視したいのでそのようにするには、DebugViewを参考にしてください。
以下のように-FIRDebugEnabled
を設定するとリアルタイムにイベントを見ることができます。(もしかしたら-FIRAnalyticsDebugEnabled
もつけないとだめかも)
Androidでイベントをデバッグ
DebugViewに書いてある通り以下のようにADBコマンドを実行すると、Firebase ConsoleのDebugViewでリアルタイムに確認することができます。
# DebugViewで確認したいとき
adb shell setprop debug.firebase.analytics.app <package_name>
# DebugViewでの確認を終了したいとき
adb shell setprop debug.firebase.analytics.app .none.
なお、ここを参考し、以下のようにするとADBでログ送信された際に見ることができます。
adb shell setprop log.tag.FA VERBOSE
adb shell setprop log.tag.FA-SVC VERBOSE
adb logcat -v time -s FA FA-SVC
参考
エラー対応
- Androidで動かしたときに
Google Play services out of date. Requires...
と出たらAndroid端末のGoogle Play開発者サービスのアプリをアップデートする. => http://qiita.com/heat2160/items/cb08c6afe3bdea75d9ab