We use Firebase Crashlytics in one of the Flutter projects that I am working on. We followed the official docs and set up Crashlytics using FlutterFire but something weird was happening. All the non-fatal errors were shown as fatal errors in the Firebase Crashlytics dashboard.
Due to this, Our crash-free users % was being shown as 26% and we panicked. I did a deep dive to find out what was wrong and figured out the issue.
After digging into the code and the Crashlytics dashboard, I figured out that all the non-fatals were being reported as fatals in the dashboard which caused a spike in the crash rate. Although this crash rate is not true and was just falsely reported in the dashboard.
Here’s the setup that we used straight from the Firebase official documentation – https://firebase.google.com/docs/crashlytics/get-started?platform=flutter
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());
}
But this setup is wrong. Read ahead to find out how to solve it.
How to solve Flutter Crashlytics showing non-fatals as fatal
Firebase Crashlytics documentation is the culprit here misleading the devs with the wrong example. Users have reported about this already – https://github.com/firebase/flutterfire/issues/9417, https://github.com/firebase/flutterfire/issues/8815
We should not use recordFlutterFatalError
in the onError
handler. Any crashes that happen don’t even reach onError
the handler of Flutter and are handled by Crashlytics natively.
So we should not use recordFlutterFatalError
unless it’s a crucial error for us to handle immediately. Fatal doesn’t always mean a crash. It means something that needs immediate attention.
Solution
- Change
recordFlutterFatalError
torecordFlutterError
- Handle async errors using
PlatformDispatcher.instance.onError
withfatal: false
because these errors are also not fatal - Optional – If needed, Identify any crucial errors with specific ids or messages and report them as fatal so that they are attended to immediately.
Conclusion
Hope that solves the issue of non-fatal errors being reported as fatal errors in the Firebase console. No more false crashes ✌️
Also read, Animated tab bar using Flutter | Can it be done with Flutter? | In-depth animation tutorial