このページでは、Crashlytics の使用に関するトラブルシューティングのヘルプ情報と、よくある質問への回答を紹介します。お探しの情報が見つからない場合や、サポートが必要な場合は、Firebase サポート にお問い合わせください。
一般的なトラブルシューティングとよくある質問
パンくずリストのログが表示されない
パンくずリストのログ(iOS+ | Android | Flutter | Unity )が表示されない場合は、アプリの Google Analytics の構成を確認することをおすすめします。次の要件を満たしていることを確認してください。
Firebase プロジェクトで Google Analytics を有効 にしています。
Google Analytics のデータ共有 を有効にしている。この設定の詳細については、アナリティクスのデータ共有設定を管理する をご覧ください。
Google Analytics 用の Firebase SDK(iOS+ | Android | Flutter | Unity )をアプリに追加している。Crashlytics SDK に加えて、この SDK も追加 する必要があります。
アプリで使用するすべてのプロダクトで最新バージョンの Firebase SDK(iOS+ | Android | Flutter | Unity )を使用している。
Apple プラットフォームと Android アプリの場合は、少なくとも次のバージョンの Google Analytics 用 Firebase SDK を使用していることを確認します。
iOS+ - v6.3.1 以降 (macOS および tvOS の場合は v8.9.0 以降)| Android - v17.2.3 以降(BoM v24.7.1 以降) 。
ベロシティ アラートが表示されない
ベロシティ アラートが表示されない場合は、
を使用していることを確認してください。
クラッシュの影響を受けていない指標が表示されない(または信頼性の低い指標が表示される)
クラッシュの影響を受けていない指標(クラッシュの影響を受けていないユーザーやセッションなど)が表示されない場合や、信頼性の低い指標が表示される場合は、次の点を確認してください。
問題に関するノートを表示、書き込み、削除できるのは誰ですか?
ノートを使用すると、特定の問題に関する質問やステータスの更新などについて、プロジェクト メンバーがコメントを残すことができます。
ノートには、投稿したメンバーの Google アカウントのメールアドレスがラベル付けされます。このメールアドレスは、ノートを見ることができるプロジェクト メンバー全員に対して、ノートとともに表示されます。
ノートを表示、書き込み、削除するために必要なアクセス権は次のとおりです。
問題の回帰とは
以前にクローズした問題が再発して Crashlytics が新しいレポートを受け取った場合に、対象の問題で回帰が発生したことになります。回帰が発生した問題は、アプリに適した方法で対応できるよう Crashlytics によって自動的に再オープンされます。
次のような場合、Crashlytics は問題を回帰として分類します。
Crashlytics が初めて、クラッシュ「A」に関するクラッシュ レポートを受け取りました。Crashlytics は、そのクラッシュに対応する問題(問題「A」)をオープンしました。
あなたはこのバグを速やかに修正し、問題「A」をクローズしてから、アプリの新しいバージョンをリリースしました。
問題をクローズした後で、Crashlytics が問題「A」に関する別のレポートを受け取りました。このレポートが、この問題をクローズしたときに Crashlytics で認識されていたバージョン(つまり、なんらかのクラッシュに関するレポートを送信したことがあるバージョン )のアプリから送信されたものである場合は、Crashlytics は問題が回帰であると見なしません。この問題はクローズのままです。
このレポートが、この問題をクローズしたときに Crashlytics で認識されていなかった バージョン(つまりクラッシュに関するレポートを以前に送信したことがないバージョン)のアプリから送信されたものである場合、Crashlytics は問題を回帰と見なして再オープンします。
注: 2022 年 2 月よりも前には、問題をクローズしたときに認識されていたアプリのバージョンである場合も含めて、Crashlytics は任意のアプリ バージョンで再発した問題を回帰として分類していました。 その結果、Crashlytics で回帰を正確に識別できないことがありました。そこで現在は、上記の規則が使用されています。 問題の回帰が発生すると、回帰検出アラートが送信されます。つまり回帰シグナルを問題に追加して、Crashlytics が問題を再オープンしたことを知らせます。この回帰アルゴリズムによって問題を再オープンしたくない場合は、問題をクローズする代わりに「ミュート」します。
古いバージョンのアプリで問題の回帰が発生するのはなぜですか?
レポートを送信したアプリのバージョンが、問題をクローズした時点でクラッシュ レポートを一度も送信したことのない古いバージョンである場合、Crashlytics は問題の回帰が発生したと見なし、その問題を再オープンします。
このような状況は、バグを修正し、新しいバージョンのアプリをリリースしたにもかかわらず、バグが修正されていない古いバージョンを利用しているユーザーがいる場合に発生することがあります。問題をクローズした時点でクラッシュ レポートを一度も送信したことのない 、古いバージョンのアプリがまだ使用されている場合、そのバージョンでバグが発生してクラッシュ レポートが送信されると、問題の回帰がトリガーされます。
この回帰アルゴリズムによって問題を再オープンしたくない場合は、問題をクローズする代わりに「ミュート」します。
注: 2022 年 2 月よりも前には、問題をクローズしたときに認識されていたアプリのバージョンである場合も含めて、Crashlytics は任意のアプリ バージョンで再発した問題を回帰として分類していました。その結果、Crashlytics で回帰を正確に識別できないことがありました。そこで現在は、上記の規則が使用されています。 2022 年 2 月以前に誤って認識された回帰が多くある場合は、それらを再クローズすることによって、再オープンを回避できます。
アプリで Google Mobile Ads SDK も使用しているが、クラッシュが取得されない
プロジェクトで Google Mobile Ads SDK と Crashlytics を併用している場合は、例外ハンドラの登録時にクラッシュ レポート機能が干渉している可能性があります。この問題を解決するには、disableSDKCrashReporting を呼び出して Mobile Ads SDK でクラッシュ レポート機能をオフにしてください。
BigQuery データセットはどこに配置されますか?
Crashlytics を BigQuery にリンクすると、作成される新しいデータセットは、Firebase プロジェクトのロケーションに関係なく自動的に米国に配置されます。
以下のセクションでは、プラットフォーム固有のトラブルシューティングとよくある質問について説明します。iOS+ | Android | Unity 。
dSYM がないか、アップロードされていない
プロジェクトの dSYM をアップロードして詳細な出力を表示するには、以下をご確認ください。
プロジェクトのビルドフェーズに Crashlytics 実行スクリプトが含まれていることを確認します。このスクリプトにより、Xcode はビルド時にプロジェクトの dSYM をアップロードできます(スクリプトの追加手順については、Crashlytics の初期化 をご覧ください)。プロジェクトを更新したら、強制的にクラッシュ させ、Crashlytics ダッシュボードにクラッシュが表示されることを確認します。
Firebase コンソールに「dSYM の不足」に関するアラートが表示される場合は、Xcode でビルドの dSYM が適切に生成されている ことを確認します。
Xcode が dSYM を適切に生成しているにもかかわらず dSYM が不足している場合は、dSYM のアップロード中に実行スクリプト ツールが停止している可能性があります。この場合は、次の手順をお試しください。
dSYM の不足やアップロードの失敗が続く場合は、Firebase サポート までご連絡ください。その際は必ず、ログを含めてください。
クラッシュのシンボリケーションが不十分
スタック トレースのシンボリケーションが不十分と思われる場合は、次の点を確認してください。
アプリのライブラリのフレームにアプリのコードへの参照がない場合は、-fomit-frame-pointer がコンパイル フラグとして設定されていないことを確認してください。
アプリのライブラリに (Missing) フレームが複数表示される場合は、Firebase コンソールの Crashlytics の [dSYMs ] タブ で、(影響を受けるアプリのバージョン用の)オプションの dSYM が不足していると表示されているかどうかを確認します。そのような表示がある場合は、このページの dSYM がないか、アップロードされていない に記載されている dSYM の不足のアラートのトラブルシューティングの手順を実施してください。これらの dSYM をアップロードしても、すでに 発生したクラッシュはシンボリケートされませんが、今後 のクラッシュはシンボリケートされるようになります。
ANR が Android 11 以降でのみ報告されるのはなぜですか?
Crashlytics は、Android 11 以降を搭載したデバイスからの Android アプリの ANR レポートをサポートしています。ANR の収集に使用される基盤となる API(getHistoricalProcessExitReasons )は、SIGQUIT やウォッチドッグ ベースの方法よりも信頼性が高くなっています。この API は Android 11 以降のデバイスでのみ使用できます。
一部の ANR に BuildId がないのはなぜですか?
一部の ANR に BuildId がない場合は、次のようにトラブルシューティングを行ってください。
最新バージョンの Crashlytics Android SDK と Crashlytics Gradle プラグインを使用していることを確認します。
Android 11 ANR と一部の Android 12 ANR に BuildId がない場合は、古い SDK または古い Gradle プラグインを使用している可能性があります。これらの ANR の BuildId を適切に収集するには、次のバージョンを使用する必要があります。
Crashlytics Android SDK v18.3.5 以降(Firebase BoM v31.2.2 以降)
Crashlytics Gradle プラグイン v2.9.4 以降
共有ライブラリで標準以外の場所を使用していないか確認します。
アプリの共有ライブラリのみの BuildId がない場合は、共有ライブラリの標準のデフォルトの場所を使用していない可能性があります。その場合、Crashlytics は関連付けられている BuildId を見つけられない可能性があります。共有ライブラリには標準の場所を使用することをおすすめします。
ビルドプロセス中に BuildId がストリップされていないことを確認します。
以下のトラブルシューティングのヒントは、ANR とネイティブ コード クラッシュのいずれに対しても有効です。
バイナリに対して readelf -n を実行して、BuildId が存在するかどうかを確認します。BuildId が存在しない場合は、ビルドシステムのフラグに -Wl,--build-id を追加します。
APK サイズを縮小する際に、誤って BuildId を削除していないことを確認します。
ストリップされているライブラリ バージョンとストリップされていないライブラリ バージョンがある場合は、コードで正しいバージョンを参照するようにしてください。
Crashlytics ダッシュボードと Google Play Console での ANR レポートの違い
Google Play と Crashlytics の間で ANR の数の不一致が発生することがあります。これは、ANR データの収集と報告のメカニズムの違いによるものです。Crashlytics はアプリが次に起動したときに ANR を報告しますが、Android Vitals は ANR の発生後に ANR データを送信します。
また、Crashlytics は、Android 11 以降を搭載したデバイスで発生した ANR のみを表示します。一方、Google Play は、Google Play 開発者サービスとデータ収集への同意が承認されているデバイスからの ANR を表示します。
.kt ファイルからのクラッシュが .java の問題であると表示されるのはなぜですか?
ファイル拡張子を公開しないようにする難読化ツールをアプリで使用している場合、Crashlytics はデフォルトで各問題を .java ファイル拡張子のものとして生成します。
Crashlytics が正しいファイル拡張子で問題を生成できるようにするには、アプリで次の設定を使用してください。
Android Gradle 4.2.0 以降を使用する
R8 を使用して難読化をオンにする。アプリを更新して R8 を使用するには、こちらのドキュメント をご覧ください。
上記の設定に更新すると、既存の .java の問題と重複する新しい .kt の問題が表示されることがあります。その状況の詳細については、よくある質問 をご覧ください。
既存の .java の問題と重複する .kt の問題が表示されるのはなぜですか?
2021 年 12 月中旬以降、Crashlytics は Kotlin を使用するアプリケーションのサポートを改善しました。
最近まで、利用可能な難読化ツールではファイル拡張子が公開されていなかったため、Crashlytics はデフォルトで .java ファイル拡張子を使用して各問題を生成していました。Android Gradle 4.2.0 以降では、R8 でファイル拡張子がサポートされています。
今回の更新で、Crashlytics はアプリで使用される各クラスが Kotlin で記述されているかどうかを判断し、問題の署名に正しいファイル名を設定できるようになりました。アプリが次の設定を使用している場合は、(状況に応じて)クラッシュが .kt ファイルのものであると正しく表示されるようになります。
アプリで Android Gradle 4.2.0 以降を使用している。
アプリで R8 を使用して難読化をオンにしている。
新しいクラッシュでは問題の署名に正しいファイル拡張子が含まれるため、.java のラベルが付けられた既存の問題と重複する新しい .kt の問題が表示されることがあります。Firebase コンソールでは、新しい .kt の問題が、.java のラベルが付けられた既存の問題と重複している可能性がある場合に、それを識別して通知することを試みています。
Dexguard でクラッシュが取得されない
以下の例外が表示される場合、Firebase Crashlytics SDK と互換性のないバージョンの DexGuard を使用している可能性があります。
java.lang.IllegalArgumentException: Transport backend 'cct' is not registered
この例外によってアプリがクラッシュすることはありませんが、クラッシュ レポートが送信されなくなります。この問題を解決する方法は以下のとおりです。
最新の DexGuard 8.x リリースを使用してください。最新バージョンには、Firebase Crashlytics SDK で必要なルールが含まれています。
DexGuard のバージョンを変更したくない場合は、DexGuard 構成ファイルの難読化ルールに次の行を追加してください。
- keepresourcexmlelements manifest / application / service / meta - data @value = cct
Crashlytics ダッシュボードと logcat の NDK スタック トレースの違い
LLVM ツールチェーンと GNU ツールチェーンはアプリのバイナリの読み取り専用セグメントに対するデフォルトの設定と処理方法がそれぞれ異なるため、Firebase コンソールで一貫性のないスタック トレースが生成される可能性があります。この問題を軽減するには、次のリンカーフラグをビルドプロセスに追加します。
スタック トレースの不整合がまだ発生している場合(またはどちらのフラグもお使いのツールチェーンに関連していない場合)は、代わりに次のリンカーフラグをビルドプロセスに追加してみてください。
-fno-omit-frame-pointer
NDK に独自の Breakpad シンボル ファイル生成ツールのバイナリを使用するにはどうすればよいですか?
Crashlytics プラグインは、カスタマイズされた Breakpad シンボル ファイル生成ツール をバンドルします。Breakpad シンボル ファイルの生成に独自のバイナリを使用する場合は(たとえば、ビルドチェーン内のすべてのネイティブの実行可能ファイルをソースからビルドする場合)、オプションの symbolGeneratorBinary 拡張プロパティを使用して、実行可能ファイルへのパスを指定します。
注: Android バイナリでは、Breakpad シンボル ファイル生成ツールの Linux バージョンが必要です。 次の 2 つの方法のいずれかで、Breakpad シンボル ファイル生成ツールのバイナリへのパスを指定できます。
オプション 1 : build.gradle ファイルの firebaseCrashlytics 拡張機能を使用してパスを指定する
アプリレベルの build.gradle.kts ファイルに以下のコマンドを追加します。
Gradle プラグイン v3.0.0 以降
android {
buildTypes {
release {
configure<CrashlyticsExtension> {
nativeSymbolUploadEnabled = true
// Add these optional fields to specify the path to the executable
symbolGeneratorType = "breakpad"
breakpadBinary = file ( "/PATH/TO/BREAKPAD/DUMP_SYMS " )
}
}
}
}
古いプラグイン バージョン
android {
// ...
buildTypes {
// ...
release {
// ...
firebaseCrashlytics {
// existing; required for either symbol file generator
nativeSymbolUploadEnabled true
// Add this optional new block to specify the path to the executable
symbolGenerator {
breakpad {
binary file ( "/PATH/TO/BREAKPAD/DUMP_SYMS " )
}
}
}
}
}
オプション 2 : Gradle プロパティ ファイルでプロパティ行を介してパスを指定する
com.google.firebase.crashlytics.breakpadBinary プロパティを使用して、実行可能ファイルのパスを指定できます。
手動で Gradle プロパティ ファイルを更新することも、コマンドラインからファイルを更新することもできます。たとえば、コマンドラインでパスを指定するには、次のようなコマンドを使用します。
./gradlew -Pcom.google.firebase.crashlytics.symbolGenerator=breakpad \
-Pcom.google.firebase.crashlytics.breakpadBinary=/PATH/TO/BREAKPAD/DUMP_SYMS \
app:assembleRelease app:uploadCrashlyticsSymbolFileRelease
Crashlytics は armeabi をサポートしていますか?
Firebase Crashlytics NDK は ARMv5(armeabi)をサポートしていません。この ABI のサポートは NDK r17 で削除されました。
Crashlytics ダッシュボードに、Android アプリのシンボリケートされていないスタック トレースが表示される
Unity の IL2CPP を使用していて、シンボリケートされていないスタック トレースが表示される場合は、次の手順をお試しください。
Crashlytics Unity SDK の v8.6.1 以降を使用していることを確認します。
シンボル ファイルを生成してアップロードするための、Firebase CLI の crashlytics:symbols:upload コマンドが設定され、実行されていることを確認します。
リリースビルドを作成するたびに、または Firebase コンソールでシンボリケートされたスタック トレースを表示するビルドを作成するたびに、この CLI コマンドを実行する必要があります。詳しくは、読み取り可能なクラッシュ レポートの取得 をご覧ください。
Crashlytics は、IL2CPP を使用するアプリと併用できますか?
はい。Crashlytics は、IL2CPP を使用するアプリに対して、シンボリケートされたスタック トレースを表示できます。この機能は、Android プラットフォームまたは Apple プラットフォームでリリースされたアプリで使用できます。必要な手順は次のとおりです。
Crashlytics Unity SDK の v8.6.0 以降を使用していることを確認します。
お使いのプラットフォームで必要なタスクを完了します。
Apple プラットフォーム アプリの場合 : 特別な操作は必要ありません。Apple プラットフォーム アプリの場合、Firebase Unity Editor プラグインが、シンボルをアップロードするように Xcode プロジェクトを自動的に構成します。
Android アプリの場合 : シンボル ファイルを生成してアップロードするための、Firebase CLI crashlytics:symbols:upload コマンドが設定され、実行されていることを確認します。
リリースビルドを作成するたびに、または Firebase コンソールでシンボリケートされたスタック トレースを表示するビルドを作成するたびに、この CLI コマンドを実行する必要があります。詳しくは、読み取り可能なクラッシュ レポートの取得 をご覧ください。
キャッチされなかった例外を致命的として報告する
Crashlytics では、キャッチされなかった例外を致命的として報告できます(Unity SDK の v10.4.0 以降)。次のよくある質問では、この機能を使用する理由とベスト プラクティスについて説明します。
キャッチされなかった例外をアプリが致命的として報告するのはなぜですか?
キャッチされなかった例外を致命的として報告することで、アプリが引き続き実行されている場合でも、例外が発生すればゲームをプレイできなくなる可能性があることをよりリアルに示すことができます。
致命的エラーの報告を開始すると、クラッシュの影響を受けていないユーザー(CFU)の割合は減少する可能性がありますが、CFU 指標はアプリによるエンドユーザー エクスペリエンスの影響を適切に反映したものになります。
重要: キャッチされなかった例外を致命的として報告しても、Android Vitals には影響しません 。
Crashlytics で報告された致命的な問題はアプリの開発者にのみ表示されるため、開発者はアプリやゲームの問題を検出して修正できます。
どのような例外が致命的として報告されますか?
キャッチされなかった例外を Crashlytics が致命的な例外として報告するには、次の 2 つの条件が両方とも満たされている必要があります。
キャッチされなかった例外を致命的として報告できるようになった後に、多くの新しい致命的な問題が発生するようになりました。このような例外を適切に処理するにはどうすればよいですか?
キャッチされなかった例外が致命的として報告されるようになった場合、これらのキャッチされなかった例外を処理する方法は、次のとおりです。
スローされた例外をキャッチして処理する
例外は、予期しない状態または例外的な状態 を反映するために作成され、スローされます。スローされた例外によって反映される問題を解決するには、プログラムを既知の状態に戻します(このプロセスは例外処理 と呼ばれます)。
プログラムを既知の状態に戻せない場合を除き、予測されるすべての 例外をキャッチして処理することをおすすめします。
キャッチするコードの種類と、キャッチした例外の処理に使用するコードを制御するには、例外を生成する可能性があるコードを try-catch ブロック内にラップ します。特定の例外を適切に処理できるように、catch ステートメントの条件をできるだけ絞り込んでください。
Unity または Crashlytics で例外をログに記録する
Unity または Crashlytics で例外を記録して問題のデバッグに役立てるには、複数の方法があります。
Crashlytics を使用する際の最も一般的な推奨オプションを 2 つ紹介します。
ただし、致命的なイベントを Unity Cloud Diagnostics に手動で報告する場合は、Debug.LogException を使用できます。このオプションでは、オプション 1 のように Unity コンソールに例外が出力されますが、(すでにスローされているのか、またはキャッチされているのかに関係なく)例外もスロー されます。ローカル以外の場所でエラーをスローします。つまり、Debug.LogException(exception) を try-catch ブロックで囲んだ場合でも、キャッチされない例外は発生します。
したがって、次のすべて の操作を行う場合にのみ、Debug.LogException を呼び出します。
Unity コンソールに例外を出力する
例外を致命的なイベントとして Crashlytics にアップロードする。
例外をスローし、キャッチされなかった例外 として処理し、Unity Cloud Diagnostics に報告する。
キャッチされた例外を Unity コンソールに出力し、 Crashlytics に致命的でないイベントとしてアップロードする場合は、代わりに次の手順を行います。
try
{
methodThatThrowsMyCustomExceptionType ();
}
catch ( MyCustomExceptionType exception )
{
// Print the exception to the Unity console at the error level.
Debug . LogError ( exception );
// Upload the exception to Crashlytics as a non-fatal event.
Crashlytics . LogException ( exception ); // not Debug.LogException
//
// Code that handles the exception
//
}