自定义 Firebase Crashlytics 崩溃报告

本指南介绍了如何使用 Crashlytics API 自定义崩溃报告。默认情况下,Crashlytics 会自动为您应用的所有用户收集平台原生崩溃报告(您也可以关闭自动崩溃报告,并为您的用户启用自选式报告)。Crashlytics 提供了五种开箱即用的日志记录机制:自定义键自定义日志用户标识符捕获的异常未捕获的异常

对于 Flutter 应用,严重报告会实时发送到 Crashlytics,而无需用户重启应用。非严重报告会写入磁盘,与下一份严重报告一起发送或在应用重启时发送。

报告未捕获的异常

您可以使用 FirebaseCrashlytics.instance.recordFlutterFatalError 替换 FlutterError.onError,自动捕获 Flutter 框架中抛出的所有“严重”错误。或者,如需在捕获“严重”异常的同时也捕获“非严重”异常,请使用 FirebaseCrashlytics.instance.recordFlutterError 替换 FlutterError.onError

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 会限制从设备发送的报告数量(如有必要)。

添加自定义键

自定义键可以帮助您获取导致崩溃的应用特定状态。 您可以将任意键值对与您的崩溃报告相关联,然后使用自定义键在 Firebase 控制台中搜索和过滤崩溃报告。

  • Crashlytics 信息中心内,您可以搜索与自定义键匹配的问题。

  • 当您在控制台中查看某个特定问题时,可以查看每个事件关联的自定义键(在“键”子标签中),甚至可以按自定义键过滤事件(使用页面顶部的“过滤条件”菜单)。

使用 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");

设置用户标识符

了解哪些用户遇到了特定的崩溃通常可以帮助您诊断问题。Crashlytics 提供了一种在崩溃报告中以匿名方式标识用户的方法。

如需将用户 ID 添加到报告中,请以 ID 编号、令牌或哈希值的形式为每个用户分配一个唯一标识符:

FirebaseCrashlytics.instance.setUserIdentifier("12345");

如果您在设置某个用户标识符后需要将其清除,请将该值重置为空字符串。清除用户标识符不会移除现有的 Crashlytics 记录。如果您需要删除与用户 ID 关联的记录,请与 Firebase 支持团队联系

启用自选式报告

默认情况下,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);
    

管理 Crash Insights 数据

Crash Insights 会比较您的匿名堆栈轨迹和来自其他 Firebase 应用的轨迹,并让您知道您的问题是否属于个例,从而帮助您解决问题。对于许多问题,Crash Insights 甚至会提供资源来帮助您调试崩溃。

Crash Insights 使用汇总的崩溃数据来识别常见的稳定性趋势。 如果您不想分享应用的数据,则可以在 Crash Insights 菜单中选择停用 Crash Insights。此菜单位于 Firebase 控制台的 Crashlytics 问题列表顶部。