sunagimoブログ

主にUnityに関する技術を取り上げます

Unityへのクラッシュレポートの導入【Firebase】

クラッシュレポートについて

アプリやソフトウェアにエラーが発生し、強制終了した際に残される情報データ。
エラーが発生した際に開発側に送られることで、開発側は早期にエラーを認知し、解決することにより、ユーザーへの早期通知及び被害の拡大を抑えることができる。



クラッシュレポートツール

Cloud Diagnostics
unity3d.com

Unityのリアルタイムクラッシュ解析ツール。
Unity Editor上より設定可能。
ライセンス形態によって、収集できるレポート数などが異なる。
Slack連携もあるらしい。

※無料


Smart Beat
smrtbeat.com

日本製のリアルタイムクラッシュ解析ツール。
数多くのサービスで導入されており、精度がとても高い。
複数のゲームエンジンに対応しており、
クラッシュ前の画面キャプチャ機能など開発者にとって、
より効率的に解決する機能も豊富。

※有料


Firebase Crashlytics
firebase.google.com

Googleのリアルタイムクラッシュ解析ツール。
AndroidiOS、Unityへ対応している。
Slack連携あり。

※無料



Firebase Crashlyticsの導入

ライセンスにより収集制限もなく、
Slackへの連携もあり更に無料で導入できるということなので
今回はFirebase Crashlyticsを選択。


【環境】
Unityのバージョン :2019.2.5f1
Crashlytics Unityバージョン:4.5.2
Crashlytics iOSバージョン:5.0.0
Crashlytics Androidバージョン:2019年9月13日更新バージョン



Firebase

Googleが提供しているモバイル及びWebアプリケーションを開発する際に
役立つ機能をまとめたもの。
mBaaSといわれている。



1. Firebaseプロジェクトの作成

以下、公式のドキュメントを参考に進めていきます。
firebase.google.com



(1)Firebaseへアクセス
https://firebase.google.com/?hl=ja


(2)プロジェクトを作成を選択
f:id:sunagimo_app:20190903010029p:plain


(3)プロジェクト名を入力
入力後、規約に同意をチェックし続行を選択。
f:id:sunagimo_app:20190903010447p:plain


(4)Googleアナリティクスの設定
後々Crashlyticsに必要となるので、有効状態のまま、続行を選択。
f:id:sunagimo_app:20190903010826p:plain


(5)アナリティクス地域はご住まいの地域に合わせて設定。
それぞれ規約を確認し、チェックボックスを選択、プロジェクトを作成を選択。
f:id:sunagimo_app:20190903011051p:plain


(6)作成されるまでしばらく待機。
f:id:sunagimo_app:20190903011143p:plain


(7)作成完了後、続行を選択。
f:id:sunagimo_app:20190903011224p:plain



2. Firebaseプロジェクトの設定

(1)UnityのプロジェクトとFirebaseプロジェクトとの結びつけを行う。
下記のUnityのマークを選択。
f:id:sunagimo_app:20190903011503p:plain


(2)Unityのプロジェクトを作成し、そのパッケージ名を
iOSAndroidそれぞれFirebaseプロジェクト側へ入力。
入力後、アプリを登録を選択。
f:id:sunagimo_app:20190917004719p:plain


(3)設定ファイルをUnityのProjectの中に配置。
Assets以下の任意の場所に配置可能。
f:id:sunagimo_app:20190917005627p:plain


(4)Firebase Unity SDKをダウンロード。
f:id:sunagimo_app:20190917010406p:plain


(5)ダウンロード後、必要なSDKをUnityのプロジェクトにインポート。
dotnet4/FirebaseAnalytics.unitypackage
dotnet4/FirebaseCrashlytics.unitypackage

f:id:sunagimo_app:20190917010800p:plain

f:id:sunagimo_app:20190917010814p:plain



(6)左上のProject OverViewを選択し、TOPページへ移動。
f:id:sunagimo_app:20190917011426p:plain


(7)Crashlyticsを選択。
f:id:sunagimo_app:20190917011630p:plain


(8)「いいえ、新しいFirebaseアプリを設定します」を選択
f:id:sunagimo_app:20190917011657p:plain


(9)ここは先程完了したのでスキップ
ドキュメントに移動を選択して、ステップ3へ
f:id:sunagimo_app:20190917011814p:plain


(10)パッケージ名、SDKを導入したAndroidiOSアプリを
実機にビルドすると、Crashlytics上でレポートが表示可能になる
f:id:sunagimo_app:20190917011840p:plain



3. Unity側の設定

(1)Firebase SDKの初期化を行うため、ソースコードを記述。
アプリ起動時などに呼び出す。
RuntimeInitializeOnLoadMethodなど

[RuntimeInitializeOnLoadMethod]
static void Initialize()
{
  Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
              var dependencyStatus = task.Result;
              if (dependencyStatus == Firebase.DependencyStatus.Available)
              {
                  Firebase.FirebaseApp app = Firebase.FirebaseApp.DefaultInstance;
              }
              else
              {
                  UnityEngine.Debug.LogError(System.String.Format(
                    "Could not resolve all Firebase dependencies: {0}",dependencyStatus));
              }
          });
}



ただ、公式ドキュメント通りだとContinueWithのコールバック内で、
UnityのMainThreadに関係する処理を呼んでしまうとアプリがクラッシュしてしまうので、Firebase.Extensionsを定義して、ContinueWithOnMainThreadを使用する。

using Firebase.Extensions;

[RuntimeInitializeOnLoadMethod]
static void Initialize()
{
  Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
              var dependencyStatus = task.Result;
              if (dependencyStatus == Firebase.DependencyStatus.Available)
              {
                  Firebase.FirebaseApp app = Firebase.FirebaseApp.DefaultInstance;
              }
              else
              {
                  UnityEngine.Debug.LogError(System.String.Format(
                    "Could not resolve all Firebase dependencies: {0}",dependencyStatus));
              }
          });
}



4. Androidへの導入時

(1)CrashlyticsのライブラリはAndroidX対応されおり、
既存のプロジェクトにAndroid Support Libraryを使用している場合はAndroid Xに対応する必要がある。
developer.android.com


(2)Android Manifest上やC#ソースコード上でJavaを記述している場合は、
以下の移行ドキュメントをもとにSupport LibraryからAndroid Xに修正する。
developer.android.com

例:
android.support.v4.util.LogWriter → androidx.core.util.LogWriter


(3)既存のライブラリでSupport Libraryを使用している場合は、
gradleファイルに記述してAndroid Xへ置き換える。
以下、記事を参考。
qiita.com



5. iOSへの導入時

iOSへの導入には2つの方法がある。
・CocoaPodsで自動でフレームワークを導入する方法
フレームワークを手動で導入する方法


(CocoaPodsで自動でフレームワークを導入する方法)

・個人開発やクラウドビルドしない場合

既にFirebase Unity SDKで用意されている、Dependenciesファイルにより
CocoaPodsで導入するフレームワーク情報が記載されている。
f:id:sunagimo_app:20190922194637p:plain



(1)ビルドするマシンにCocoaPodsを導入する

homebrew

brew install cocoapods 

gem

sudo gem install cocoapods

もしくは

sudo gem install -n /usr/local/bin cocoapods

予めマシンに導入しておくことで、Xcodeビルド時に自動で必要なフレームワーク
導入される。



フレームワークを手動で導入する方法)

・チーム開発
・Cloud Build、Jenkinsでビルドする場合

firebase.google.com



(1)以下、公式ドキュメントよりの「Crashlytics SDKをダウンロードします。」
からフレームワークをダウンロード。
f:id:sunagimo_app:20190922200200p:plain


(2)ダウンロードした、
Crashlytics.framework
Fabric.framework

をUnityのAssses/Plugins/iOS以下に配置する。
f:id:sunagimo_app:20190922200333p:plain


(3)CocoaPodsの定義を削除

AnalyticsDependencies.xml
AppDependencies.xml
CrashlyticsDependencis.xml
にある以下を削除。

f:id:sunagimo_app:20190922202018p:plain



Firebase Crashlyticsの機能


1.送信されるタイミングと出力可能なエラー


送信されるタイミング
1.エラー発生
2.アプリ終了
3.アプリ起動(ここでクラッシュレポートが送信される)


出力可能なエラー

・Unity API系のエラー
Null Reference Exceptionなど
docs.unity3d.com

Debug.LogErrorは出力されない。



・システム系のエラー
System.ArgumentExceptionなど
docs.microsoft.com



・ネイティブ系のエラー
ClassNotFoundExceptionなど
docs.oracle.com



2.レポートのカスタマイズ

・ユーザーIDの登録
送信するレポートに識別子のID情報を付け加えることができる。
Firebase SDK初期化成功時に呼び出す。
Crashlytics上で設定した識別子IDで検索が可能。

Crashlytics.SetUserId("userId");


・レポートへのキー、詳細ログ登録
出力されるレポートに対して、更に詳細な情報を付け足すことが可能

(キーの登録)

Crashlytics.SetCustomKey("key1", "test");


(詳細ログ登録)

Crashlytics.Log("詳細ログ");


・意図的にエラレポートを出力する

void ForceOutputError()
{
 try
 {
  throw new InvalidOperationException("forceError");
 }
 catch(InvalidOperationException ex)
 {
  Crashlytics.LogException(ex);
 }
}


3.Crashlytics Consoleの機能

・アプリバージョンごとの抽出
f:id:sunagimo_app:20190922215219p:plain
f:id:sunagimo_app:20190922215229p:plain


・期間ごとの抽出
f:id:sunagimo_app:20190922215346p:plain


・OS、デバイスによる抽出
f:id:sunagimo_app:20190922215423p:plain
f:id:sunagimo_app:20190922215444p:plain


・ユーザーIDによる抽出
f:id:sunagimo_app:20190922215605p:plain
f:id:sunagimo_app:20190922215617p:plain


・クラッシュレポートの詳細
スタックトレースを確認可能
f:id:sunagimo_app:20190922215655p:plain
f:id:sunagimo_app:20190922215709p:plain


・レポートのステータス更新
レポートをタスクとして管理することが可能。
閉じたり、メモを残すことができる。
f:id:sunagimo_app:20190922215821p:plain


4.Slackとの連携

Slackと連携をすることで、クラッシュレポートが送信された際に通知を受け取ることができる。

(1)Firebaseプロジェクトの設定ページを選択
f:id:sunagimo_app:20190922223935p:plain
f:id:sunagimo_app:20190922224401p:plain


(2)連携機能を選択
f:id:sunagimo_app:20190922224419p:plain


(3)Slackをインストール
f:id:sunagimo_app:20190922224443p:plain


(4)Slackの情報を入力
・Incoming Webhook URL
・チャンネル
・投稿ユーザー名

f:id:sunagimo_app:20190922224605p:plain

WebHookURLはここから取得
https://slack.com/services/new/incoming-webhook

チャンネルを指定してWebHookURLを取得
f:id:sunagimo_app:20190922224744p:plain


(5)通知の送信設定
デフォルトでは2つしかチェックが付いていないので、
全てにチェックを入れておく
f:id:sunagimo_app:20190922225148p:plain


まとめ

・Firebase Crashlyticsは無料
・Unity APIのエラー検知が可能
・通知数の制限なし
・Slackへの連携が可能