firebase-crashlytics

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Firebase Crashlytics Skill

Firebase Crashlytics 技能指南

This skill defines how to correctly use Firebase Crashlytics in Flutter applications.
本技能介绍如何在Flutter应用中正确使用Firebase Crashlytics。

When to Use

适用场景

Use this skill when:
  • Setting up Crashlytics in a Flutter project.
  • Configuring fatal and non-fatal error handling.
  • Customizing crash reports with keys, logs, and user identifiers.
  • Testing crash reporting or configuring opt-in data collection.

在以下场景中使用本技能:
  • 在Flutter项目中设置Crashlytics时。
  • 配置致命与非致命错误处理时。
  • 使用键、日志和用户标识符自定义崩溃报告时。
  • 测试崩溃报告或配置选择性加入数据收集时。

1. Setup and Configuration

1. 安装与配置

flutter pub add firebase_crashlytics
flutter pub add firebase_analytics  # enables breadcrumb logs for better crash context
Run
flutterfire configure
to update your Firebase configuration and add the required Crashlytics Gradle plugin for Android.
dart
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
Obfuscated code:
  • For apps built with
    --split-debug-info
    and/or
    --obfuscate
    , upload symbol files for readable stack traces.
  • iOS: Flutter 3.12.0+ and Crashlytics Flutter plugin 3.3.4+ handle symbol upload automatically.
  • Android: Use Firebase CLI (v11.9.0+) to upload Flutter debug symbols before reporting crashes:
bash
firebase crashlytics:symbols:upload --app=FIREBASE_APP_ID PATH/TO/symbols

flutter pub add firebase_crashlytics
flutter pub add firebase_analytics  # enables breadcrumb logs for better crash context
运行
flutterfire configure
以更新您的Firebase配置,并为Android添加所需的Crashlytics Gradle插件。
dart
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
代码混淆处理:
  • 对于使用
    --split-debug-info
    和/或
    --obfuscate
    构建的应用,上传符号文件以获得可读的堆栈跟踪。
  • iOS: Flutter 3.12.0+和Crashlytics Flutter插件3.3.4+会自动处理符号上传。
  • Android: 使用Firebase CLI(v11.9.0+)在报告崩溃前上传Flutter调试符号:
bash
firebase crashlytics:symbols:upload --app=FIREBASE_APP_ID PATH/TO/symbols

2. Error Handling

2. 错误处理

Fatal Flutter errors:
dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  // Pass all uncaught fatal errors from the framework to Crashlytics
  FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;

  runApp(MyApp());
}
Non-fatal Flutter errors: use
recordFlutterError
instead of
recordFlutterFatalError
.
Async errors not caught by the Flutter framework:
dart
PlatformDispatcher.instance.onError = (error, stack) {
  FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
  return true;
};
Isolate errors:
dart
Isolate.current.addErrorListener(RawReceivePort((pair) async {
  final List<dynamic> errorAndStacktrace = pair;
  await FirebaseCrashlytics.instance.recordError(
    errorAndStacktrace.first,
    errorAndStacktrace.last,
    fatal: true,
  );
}).sendPort);
Caught exceptions (non-fatal):
dart
await FirebaseCrashlytics.instance.recordError(
  error,
  stackTrace,
  reason: 'a non-fatal error',
  information: ['further diagnostic information about the error', 'version 2.0'],
);
  • Crashlytics only stores the most recent 8 non-fatal exceptions per session — older ones are discarded.

Flutter致命错误:
dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  // Pass all uncaught fatal errors from the framework to Crashlytics
  FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;

  runApp(MyApp());
}
Flutter非致命错误: 使用
recordFlutterError
替代
recordFlutterFatalError
Flutter框架未捕获的异步错误:
dart
PlatformDispatcher.instance.onError = (error, stack) {
  FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
  return true;
};
Isolate错误:
dart
Isolate.current.addErrorListener(RawReceivePort((pair) async {
  final List<dynamic> errorAndStacktrace = pair;
  await FirebaseCrashlytics.instance.recordError(
    errorAndStacktrace.first,
    errorAndStacktrace.last,
    fatal: true,
  );
}).sendPort);
已捕获的异常(非致命):
dart
await FirebaseCrashlytics.instance.recordError(
  error,
  stackTrace,
  reason: 'a non-fatal error',
  information: ['further diagnostic information about the error', 'version 2.0'],
);
  • Crashlytics每个会话仅存储最近8条非致命异常 — 旧的异常会被丢弃。

3. Crash Report Customization

3. 崩溃报告自定义

Custom keys (max 64 key/value pairs, up to 1 kB each):
dart
FirebaseCrashlytics.instance.setCustomKey('str_key', 'hello');
FirebaseCrashlytics.instance.setCustomKey('bool_key', true);
FirebaseCrashlytics.instance.setCustomKey('int_key', 1);
Custom log messages (limit: 64 kB per session):
dart
FirebaseCrashlytics.instance.log("User tapped on payment button");
User identifier:
dart
FirebaseCrashlytics.instance.setUserIdentifier("user-123");
// Clear by setting to blank string
FirebaseCrashlytics.instance.setUserIdentifier("");
  • Avoid putting unique values (user IDs, timestamps) directly in exception messages — use custom keys instead.

自定义键(最多64个键值对,每个最多1 kB):
dart
FirebaseCrashlytics.instance.setCustomKey('str_key', 'hello');
FirebaseCrashlytics.instance.setCustomKey('bool_key', true);
FirebaseCrashlytics.instance.setCustomKey('int_key', 1);
自定义日志消息(限制:每个会话64 kB):
dart
FirebaseCrashlytics.instance.log("User tapped on payment button");
用户标识符:
dart
FirebaseCrashlytics.instance.setUserIdentifier("user-123");
// Clear by setting to blank string
FirebaseCrashlytics.instance.setUserIdentifier("");
  • 避免将唯一值(用户ID、时间戳)直接放入异常消息中 — 请改用自定义键。

4. Performance and Optimization

4. 性能与优化

  • Crashlytics processes exceptions on a dedicated background thread to minimize performance impact.
  • Fatal reports are sent in real-time without requiring an app restart.
  • Non-fatal reports are written to disk and sent with the next fatal report or on app restart.
  • Crashlytics rate-limits reports from a device to reduce network traffic if necessary.
  • Use breadcrumb logs (requires Firebase Analytics) to understand user actions leading up to a crash.
Disable Crashlytics in debug builds:
dart
if (kReleaseMode) {
  await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
} else {
  await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(false);
}

  • Crashlytics在专用后台线程上处理异常,以最小化对性能的影响。
  • 致命报告实时发送,无需重启应用。
  • 非致命报告写入磁盘,会随下一条致命报告或应用重启时发送。
  • 必要时,Crashlytics会对设备的报告进行速率限制,以减少网络流量。
  • 使用面包屑日志(需Firebase Analytics)了解崩溃发生前的用户操作。
在调试构建中禁用Crashlytics:
dart
if (kReleaseMode) {
  await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
} else {
  await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(false);
}

5. Testing and Debugging

5. 测试与调试

Force a test crash to verify your setup:
dart
FirebaseCrashlytics.instance.crash();
  • Test both fatal and non-fatal error reporting.
  • Verify stack traces are properly symbolicated when using code obfuscation.
  • Check that custom keys, logs, and user identifiers are associated with crash reports.
  • Monitor the Crashlytics dashboard regularly and set up alerts for new issues or regressions.

强制触发测试崩溃以验证设置:
dart
FirebaseCrashlytics.instance.crash();
  • 测试致命和非致命错误报告功能。
  • 验证使用代码混淆时堆栈跟踪是否已正确符号化。
  • 检查自定义键、日志和用户标识符是否与崩溃报告关联。
  • 定期监控Crashlytics控制台,并为新问题或回归设置警报。

6. Opt-in Reporting

6. 选择性加入报告

By default, Crashlytics automatically collects crash reports for all users.
To give users control over data collection:
  • Disable automatic reporting and enable it only via
    setCrashlyticsCollectionEnabled(true)
    when users opt in.
  • The override value persists across all subsequent app launches.
  • To opt a user out, pass
    false
    — this applies from the next app launch.
  • When disabled, crash info is stored locally; if later enabled, locally stored crashes are sent to Crashlytics.

默认情况下,Crashlytics会自动为所有用户收集崩溃报告。
若要让用户控制数据收集:
  • 禁用自动报告,仅当用户选择加入时通过
    setCrashlyticsCollectionEnabled(true)
    启用。
  • 该覆盖值会持久保留在后续所有应用启动中。
  • 若要让用户退出,传入
    false
    — 该设置将从下次应用启动时生效。
  • 禁用时,崩溃信息会本地存储;若后续重新启用,本地存储的崩溃会发送至Crashlytics。

References

参考资料