Firebase Crashlytics のクラッシュ レポートのカスタマイズ

Crashlytics ダッシュボードで問題をクリックすると、詳細なイベント レポートが表示されます。これらのレポートをカスタマイズすると、アプリの動作や、Crashlytics に報告されるイベントに関する状況を詳細に把握できるようになります。

キャッチされなかった例外を報告する

FlutterError.onErrorFirebaseCrashlytics.instance.recordFlutterFatalError でオーバーライドすると、Flutter フレームワーク内でスローされたすべての「致命的な」エラーを自動的にキャッチできます。「致命的でない」例外もキャッチするには、FlutterError.onErrorFirebaseCrashlytics.instance.recordFlutterError でオーバーライドします。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp();
  bool weWantFatalErrorRecording = true;
  FlutterError.onError = (errorDetails) {
    if(weWantFatalErrorRecording){
      FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
    } else {
      FirebaseCrashlytics.instance.recordFlutterError(errorDetails);
    }
  };

  runApp(MyApp());
}

非同期エラー

Flutter フレームワークで非同期エラーをキャッチすることはできません。

ElevatedButton(
  onPressed: () async {
    throw Error();
  }
  ...
)

このようなエラーをキャッチするには、PlatformDispatcher.instance.onError ハンドラを使用します。

Future<void> main() async {
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp();
    FlutterError.onError = (errorDetails) {
      FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
    };
    // Pass all uncaught asynchronous errors that aren't handled by the Flutter framework to Crashlytics
    PlatformDispatcher.instance.onError = (error, stack) {
      FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
      return true;
    };
    runApp(MyApp());

}

Flutter 外部のエラー

Flutter コンテキストの外部で発生したエラーをキャッチするには、現在の Isolate にエラーリスナーをインストールします。

Isolate.current.addErrorListener(RawReceivePort((pair) async {
  final List<dynamic> errorAndStacktrace = pair;
  await FirebaseCrashlytics.instance.recordError(
    errorAndStacktrace.first,
    errorAndStacktrace.last,
    fatal: true,
  );
}).sendPort);

キャッチされた例外を報告する

Crashlytics では、アプリのクラッシュを自動的に報告するだけでなく、致命的でない例外を記録して、次に致命的なイベントを報告するときに一緒に送信できます。また、アプリの再起動時にも例外を送信できます。

recordError メソッドを使用して、致命的でない例外をアプリの catch ブロックに記録します。例:

await FirebaseCrashlytics.instance.recordError(
  error,
  stackTrace,
  reason: 'a non-fatal error'
);

// Or you can use:
await FirebaseCrashlytics.instance.recordFlutterError(errorDetails);

また、information プロパティを使用して、発生する可能性のあるエラーの詳細をログに記録することもできます。

await FirebaseCrashlytics.instance.recordError(
  error,
  stackTrace,
  reason: 'a non-fatal error',
  information: ['further diagnostic information about the error', 'version 2.0'],
);

このような例外は、Firebase コンソールでは非致命的な問題として表示されます。問題の概要には、クラッシュの場合に通常表示されるすべての状態情報に加え、バージョンとハードウェア デバイスごとの内訳が示されます。

Crashlytics はアプリのパフォーマンスへの影響を最小限に抑えるために、専用のバックグラウンド スレッドで例外を処理します。ユーザーのネットワーク トラフィックを少なくするため、Crashlytics は必要に応じて、デバイスから送信されるレポート数にレート制限を適用します。

カスタムキーを追加する

カスタムキーを使用して、クラッシュにつながったアプリの特定の状態を把握できます。任意の Key-Value ペアをクラッシュ レポートに関連付けてから、Firebase コンソールでカスタムキーを使用してクラッシュ レポートを検索、フィルタできます。

  • Crashlytics ダッシュボードで、カスタムキーと一致する問題を検索できます。

  • コンソールで特定の問題を確認するには、各イベントに関連付けられているカスタムキーを表示します([キー] サブタブ)。カスタムキーでイベントをフィルタすることもできます(ページ上部にある [フィルタ] メニュー)。

Key-Value ペアを設定するには、setCustomKey インスタンス メソッドを使用します。次に例を示します。

// Set a key to a string.
FirebaseCrashlytics.instance.setCustomKey('str_key', 'hello');

// Set a key to a boolean.
FirebaseCrashlytics.instance.setCustomKey("bool_key", true);

// Set a key to an int.
FirebaseCrashlytics.instance.setCustomKey("int_key", 1);

// Set a key to a long.
FirebaseCrashlytics.instance.setCustomKey("int_key", 1L);

// Set a key to a float.
FirebaseCrashlytics.instance.setCustomKey("float_key", 1.0f);

// Set a key to a double.
FirebaseCrashlytics.instance.setCustomKey("double_key", 1.0);

カスタムログ メッセージを追加する

クラッシュにつながったイベントのコンテキストをさらに詳細に把握するには、Crashlytics カスタムログをアプリに追加します。Crashlytics は、ログをクラッシュ データに関連付けて、Firebase コンソールの Crashlytics の [ログ] タブに表示します。

log を使用して、問題を特定できるようにします。次に例を示します。

FirebaseCrashlytics.instance.log("Higgs-Boson detected! Bailing out");

ユーザー ID を設定する

問題を診断する際には、多くの場合、特定のクラッシュがどのユーザーで発生したかを把握すると役立ちます。Crashlytics には、クラッシュ レポート内でユーザーを匿名で識別する手段が用意されています。

レポートにユーザー ID を追加するには、各ユーザーに ID 番号、トークン、またはハッシュ値の形で一意の ID を割り当てます。

FirebaseCrashlytics.instance.setUserIdentifier("12345");

ユーザー ID を設定後にクリアする必要が生じた場合は、ID の値を空白の文字列にリセットします。ユーザー ID をクリアしても、既存の Crashlytics レコードが削除されることはありません。ユーザー ID に関連付けられたレコードを削除する必要がある場合は、Firebase サポートにお問い合わせください

パンくずリストのログを取得する

パンくずリストのログで、クラッシュ イベント、非致命的イベント、ANR イベントに至るまでにユーザーがアプリで行った操作を詳しく把握できます。これらのログは、問題の再現とデバッグを行う際に役立ちます。

パンくずリストのログは Google アナリティクスを利用しているため、パンくずリストのログを取得するには、Firebase プロジェクトで Google アナリティクスを有効にして、Google アナリティクス用の Firebase SD をアプリに追加する必要があります。これらの要件を満たしている場合に、問題の詳細を表示すると、[ログ] タブにパンくずリストのログとイベントのデータが自動的に追加されます。

アナリティクス SDK は screen_view イベントを自動的にログに記録します。これにより、パンくずリストログに、クラッシュ イベント、非致命的イベント、ANR イベントの前の表示画面の一覧を示すことができます。screen_view パンくずリストログには firebase_screen_class パラメータが含まれます。

パンくずリストログには、ユーザーのセッション内で手動で記録したカスタム イベント(イベントのパラメータ データなど)も入力されます。このデータは、クラッシュ イベント、非致命的イベント、ANR イベントにつながる一連のユーザー操作を把握するのに役立ちます。

パンくずリストのログに入力されるデータを含め、Google アナリティクス データの収集と使用を制御できます。

オプトイン レポートを有効にする

デフォルトでは、Crashlytics は自動的にアプリの全ユーザーを対象にクラッシュ レポートを収集します。どのデータを送信するかをユーザーが細かく制御できるようにするには、オプトイン レポートを有効にします。これを行うには、自動レポートを無効にし、コード内で選択した場合のみデータを Crashlytics に送信するようにします。

  1. ネイティブでの自動収集を無効にします。

    Apple プラットフォーム

    Info.plist ファイルに新しいキーを追加します。

    • キー: FirebaseCrashlyticsCollectionEnabled
    • 値: false

    Android

    AndroidManifest.xml ファイルの application ブロックに、meta-data タグを追加して自動収集を無効にします。

    <meta-data
        android:name="firebase_crashlytics_collection_enabled"
        android:value="false" />
    
  2. 実行時に Crashlytics データ収集オーバーライドを呼び出して、選択したユーザーで収集を有効にします。

    オーバーライド値はアプリが再起動されても維持されるため、Crashlytics は自動的にレポートを収集できます。自動クラッシュ レポートを無効にするには、オーバーライド値として false を渡します。false に設定された場合、この新しい値はアプリが次回実行されるまで適用されません。

    FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
    

クラッシュ分析データを管理する

クラッシュ分析では、匿名化されたスタック トレースと他の Firebase アプリのトレースを比較して、発生した問題がより大きい傾向の一部であるかどうかが通知されるので、問題の解決に役立ちます。また、多くの問題について、クラッシュのデバッグに役立つリソースも提供されます。

クラッシュ分析は、集計されたクラッシュ データを使用して、一般的な安定性の傾向を特定します。アプリのデータを共有しない場合は、Firebase コンソールの Crashlytics 問題リストの最上部にある [クラッシュ分析情報の設定] メニューからクラッシュ分析を無効にできます。