Skip to main content

firebase_crashlytics

PackageKindProvides the roleNeedsChoose with
smf_firebase_crashlyticsinfrastructureCrash reportingfirebase_core-m firebase_crashlytics

firebase_crashlytics reports errors to Firebase Crashlytics with the firebase_crashlytics package: the errors that the app does not handle, and those that its code reports.

What it adds to the app​

The module adds firebase_crashlytics: ^5.4.0 to the dependencies, and lib/core/crash_reporting/crashlytics_crash_reporter.dart with the reporter on FirebaseCrashlytics.instance.

Whichever module provides it, the crash reporting role adds lib/core/crash_reporting/crash_reporter.dart with:

  • the CrashReporter interface, where recordError and recordFlutterError report an error, log adds a message to the log sent with the next report, and setUserId sets the id of the signed-in user or clears it with null;
  • createCrashReporter(), which returns the reporter of the app, a reporter that forwards every call to the reporters of all the modules that provide crash reporting, each on its own, so an app can report to more than one service and a reporter that fails affects no other;
  • installCrashReporting(), which reports as fatal the errors of the main isolate that the app does not handle.

In its platform phase, bootstrap() initializes Firebase and then calls installCrashReporting().

In the guide for coding agents of the app, the crash reporting role describes the reporter under "Crash reporting". The module adds to report through CrashReporter and not through FirebaseCrashlytics.instance, and says that tool/configure_firebase.dart keeps the build phase working for flutter build ipa.

What gets reported and printed​

  • Flutter still presents an error that it catches, such as one in a build, as it does by default, in every mode. The reporter sends the same report that recordFlutterError of Crashlytics sends.
  • Any other uncaught error goes to recordError, and in debug mode the engine still prints it.
  • The reporter itself prints nothing, so an error that the code of the app reports is not printed either. When a call to Crashlytics fails, the reporter of the app prints the failure in debug mode.
  • setUserId(null) clears the id of the user by setting an empty one, as Crashlytics does.

The handlers cover the main isolate. For errors of other isolates, see Services and state.

Getting the reporter​

The reporter is created on first use, without waiting. With a module of dependency injection, the role registers it in the container as a lazy singleton, and a feature takes it with resolve in its composition file. Without a container, the code of the app calls createCrashReporter().

Native setup​

The module generates nothing in the native projects. tool/configure_firebase.dart of firebase_core has flutterfire add what Crashlytics needs to an app that depends on firebase_crashlytics, such as the build phase that uploads the debug symbols on macOS.

The phase of flutterfire_cli 1.4.1 does not find the upload script when flutter build ipa archives the app. flutterfire writes the phase again in each of its runs, so the module adds tool/firebase_configured/fix_crashlytics_phase.dart, which that script runs after each flavor. On macOS it points the phase at the upload script where Flutter puts it, and elsewhere it does nothing. The Crashlytics section of the README of the app gives its command, for when you run flutterfire configure yourself. See Firebase.

The phase looks up the build configuration in firebase.json, so on macOS a build of a flavor that is not configured fails there once another flavor is. See A flavor that is not configured.

Choosing it​

smf create asks which modules provide the crash reporting of the app, and the answer may be none. To choose it without the question, name it in -m, and firebase_core comes with it:

smf create my_app -m firebase_crashlytics