App crashes happen all the time. They disrupt users while playing games, streaming movies, or using social media. For a developer, it is crucial to prevent such issues and ensure a positive smooth user experience to retain and grow your app's user base.
However, achieving a completely bug-free app is unlikely. And the best remaining approach is to be ready to identify and address bugs promptly once they occur to some users. This can be achieved by releasing timely updates that patch and resolve these issues ASAP before other users encounter them.
To accomplish this, you first need a reliable system that can report errors within your app after users have installed it. In a nutshell, this reporting system will send you the logs and the stack trace for the errors in your app. Luckily enough, there are reliable services out there which have become industry standards for this purpose. Firebase Crashlytics can assist you in quickly identifying and taking action against any problems within your app.
What is Crashlytics?
Crashlytics is one of the many services Firebase offers to enhance the development cycle for developers and help them build reliable and high-quality apps. The Crashlytics service collects and reports the analytics related to crashes, errors, exceptions, and logs within your app. It collects these types of data from your user base and provides insights for any critical or uncritical issues that might affect your app user experience.
Crashlytics requires you to manually integrate its SDK into your app, making it usable for apps distributed through any platform, not just on the Play Store. This feature sets Crashlytics apart from Google Play crash reporting, which is available for Play Store apps. Crashlytics can seamlessly integrate into projects built for Apple, Android, Flutter, and Unity, offering compatibility and flexibility across different platforms.
How does it work?
- Logging. You need to log important events in your app so that Crashlytics can gather them and show you the context and the user's pathway that lead to the crash.
- Stack tracing. Even if your application manages to recover from an error by capturing and handling it, the stack trace can still be captured and forwarded to you.
- Crash reporting. Every crash is transformed into a comprehensive crash report automatically sent when the application is started again. Using an analysis engine, Crashlytics groups similar events by comparing the error messages, error codes, and where the problems occurred in the app. These grouped events are called "issues," and the more events that match the issue, the higher this issue is ranked in the Crashlytics dashboard. This helps you prioritize and fix the most critical problems first.
How to set it up?
As mentioned earlier, Crashlytics is a Firebase service, meaning you need to integrate Firebase before you can use it. This involves creating a Firebase project, adding your app to Firebase, and downloading a configuration file. Assuming you are already familiar with these steps, let's discuss how to add Crashlytics in more detail.
1. In the app-level Gradle file, add the dependency for the Crashlytics Android library. It is recommended to use the Firebase Android BoM to control the library versioning. Firebase Android BoM will ensure you always use compatible versions of Firebase Android libraries.
dependencies {
// Add the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:32.1.0')
// While using the BoM, you don't specify the versions for the Firebase library dependencies
// Add the Crashlytics library dependency
implementation 'com.google.firebase:firebase-crashlytics-ktx'
}
2. In the project-level Gradle file, add the Crashlytics Gradle plugin:
buildscript {
repositories {
// You need to have the following two repositories
google() // Google's Maven repository
mavenCentral() // Maven Central repository
}
dependencies {
...
classpath 'com.android.tools.build:gradle:7.2.0'
// You need to have the Google services Gradle plugin dependency
classpath 'com.google.gms:google-services:4.3.15'
// Add the dependency for the Crashlytics Gradle plugin
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.5'
}
}
3. In the app-level Gradle file, add the Crashlytics Gradle plugin:
plugins {
id 'com.android.application'
// You need to have the Google services Gradle plugin
id 'com.google.gms.google-services'
// Add the Crashlytics Gradle plugin
id 'com.google.firebase.crashlytics'
...
}Testing the setup
In order to test the setup, we need to force a crash so that we can make sure that everything is connected all right and the crash would show up on your online Crashlytics dashboard. In one of your activities, add the following code that creates a button that, when clicked, crashes your application.
val button = Button(this)
button.text = "Crash Test"
button.setOnClickListener {
throw RuntimeException("Crash Test") // Force the app to crash
}
addContentView(button, ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT))
Build and run your app on the emulator or a test device, then click on the Crash Test button. Once the app crashes, relaunch it to allow Crashlytics to send you the crash report. Then go to your online Crashlytics dashboard to see your very first test crash.
Keep in mind that the reports are typically sent in the subsequent app run. Although the Crashlytics SDK is not often able to send the report immediately after the app crashes and closes, there is a slight possibility it might succeed within this short timeframe.
A more comprehensive crash report
To customize your reports and include more relevant data based on your use case, Crashlytics SDK provides the following four functionalities: custom keys, custom logs, user identifiers, and caught exceptions.
- Custom keys: use them when you want to include other variables from your app in the crash reports sent to you because you think they would be relevant in helping you identify the problem. You can include up to 64 key/value pairs. Each pair can reach 1kB in size.
Firebase.crashlytics.setCustomKeys { key("key_1", "Wow") // String value key("key_2", true) // boolean value key("key_3", 2.0) // double value key("key_4", 9) // int value } - Custom logs: use them when you need more context about the use case and the events that the user has gone through just before the crash. You can add logs that would be bundled with the crash data and displayed under the Logs tab in the Crashlytics dashboard.
Firebase.crashlytics.log("Logging In") - User identifiers: use them when you need to know which users experienced a specific crash or error. They might help figure out that some errors are related because they originate from the same users. Crashlytics allows you to identify users in your custom crash reports.
Firebase.crashlytics.setUserId("00012") - Caught exceptions: you can collect and send non-fatal exceptions which are caught within your app. Crashlytics allows you to record up to 8 exceptions which will be sent the next time your app is launched. If your app throws more than eight exceptions, only the newest 8 exceptions are recorded.
try { // Code that can possibly throw an error ... } catch (e: Exception) { // Record Exceptions using Crashlytics Firebase.crashlytics.recordException(e) ... }
Conclusion
Firebase Crashlytics is a powerful tool for developers to collect and report crash-related analytics and errors the next time your app launches. By integrating Crashlytics into your app, you can log events, capture stack traces, and receive comprehensive crash reports to identify and resolve issues quickly. It supports multiple platforms and requires manual integration by adding dependencies and plugins to your project.