Crash Reporting with Crashlytics
Overview
Crash reporting lets you find out when and why your app crashes in the wild, instead of relying on user complaints or store reviews. Firebase Crashlytics is Google’s crash reporter for Android: it captures fatal crashes, recorded (non-fatal) exceptions, and the logs, keys, and user identifiers you attach to them, then groups similar stack traces into issues on a realtime dashboard.
A brief history: Crashlytics began as part of Twitter’s Fabric.io platform. After Google acquired Fabric, Crashlytics was rebuilt as Firebase Crashlytics, and the legacy Fabric SDK stopped sending crash reports on November 15, 2020, per the Firebase blog post It’s Time to Upgrade to the New Firebase Crashlytics SDK!. This page covers the current Firebase Crashlytics SDK; a short historical note on the Fabric-era setup is at the bottom. (This wiki’s Crash Reporting with Firebase page covers the unrelated, now-sunset standalone Firebase Crash Reporting SDK.)
Setup
Prerequisites
Crashlytics requires your app to be connected to a Firebase project. If you haven’t done that yet, follow the official Add Firebase to your Android project guide (create a Firebase project in the Firebase console, register your app’s package name, and drop the generated google-services.json into your app module). See also this wiki’s Building Data-driven Apps with Firebase guide.
Per the Crashlytics getting-started guide, the minimum toolchain is Gradle 8.0, Android Gradle Plugin 8.1.0, and Google services Gradle plugin 4.4.1.
Add the Crashlytics Gradle plugin
In your root-level build.gradle.kts, declare the Google services plugin and the Crashlytics plugin alongside the Android plugin (versions shown are the ones current in the getting-started guide as of August 2026 — check that page for the latest):
plugins {
id("com.android.application") version "8.1.4" apply false
id("com.google.gms.google-services") version "4.5.0" apply false
id("com.google.firebase.crashlytics") version "3.0.7" apply false
}
Then apply both plugins in your app-level build.gradle.kts:
plugins {
id("com.android.application")
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
}
The Crashlytics Gradle plugin takes care of uploading ProGuard/R8 mapping files (and native symbols, if configured) so your stack traces arrive deobfuscated.
Add the SDK dependencies
In the app-level build.gradle.kts, import the Firebase Android BoM and add the Crashlytics dependency. Adding firebase-analytics is optional but recommended — it powers breadcrumb logs (the user actions leading up to a crash) and crash-free-user metrics:
dependencies {
// Firebase BoM pins compatible versions for all Firebase libraries
implementation(platform("com.google.firebase:firebase-bom:34.17.0"))
implementation("com.google.firebase:firebase-crashlytics")
implementation("com.google.firebase:firebase-analytics")
}
Because the BoM controls the versions, the individual Firebase artifacts take no version suffix. BoM 34.17.0 (which maps to firebase-crashlytics 20.1.0) was released July 30, 2026 per the Firebase Android release notes; Firebase artifacts are published to the Google Maven repository (google()), not Maven Central. Note that the Kotlin extensions now live in the main firebase-crashlytics module — the separate -ktx artifact is deprecated per the release notes.
That’s the whole setup: once the plugins and dependency are in place, Crashlytics automatically installs an uncaught-exception handler at app start. No initialization code is required.
Verify the setup with a forced crash
Add a button that deliberately crashes the app, following the getting-started guide:
val crashButton = Button(this)
crashButton.text = "Test Crash"
crashButton.setOnClickListener {
throw RuntimeException("Test Crash") // Force a crash
}
or in Java:
Button crashButton = new Button(this);
crashButton.setText("Test Crash");
crashButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
throw new RuntimeException("Test Crash"); // Force a crash
}
});
Run the app, tap the button to crash it, then relaunch the app — Crashlytics sends pending crash reports on the next launch. The crash should appear within a few minutes on the Crashlytics dashboard in the Firebase console (select your project, then Crashlytics in the left navigation). The dashboard groups crashes with similar stack traces into issues and tracks affected-user counts and crash-free-session rates. Remember to remove the test button before shipping.
Enhance crash reports
Beyond automatic crash capture, Crashlytics offers four ways to add context, documented in Customize your Crashlytics crash reports. In Kotlin the entry point is the Firebase.crashlytics accessor; in Java it is FirebaseCrashlytics.getInstance().
Recorded (non-fatal) exceptions
Exceptions you catch and recover from can still be reported; they show up as non-fatal issues on the dashboard. Crashlytics stores only the most recent eight recorded exceptions per session and sends them on the next app launch:
import com.google.firebase.Firebase
import com.google.firebase.crashlytics.crashlytics
try {
myMethodThatThrows()
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
// handle the exception here
}
FirebaseCrashlytics.getInstance().recordException(e);
Custom logging
Logged messages are attached to the next crash or recorded exception and are visible on that event’s detail page. Logs are capped at 64 kB per session; older entries are dropped past that limit:
Firebase.crashlytics.log("Higgs-Boson detected! Bailing out...")
FirebaseCrashlytics.getInstance().log("Higgs-Boson detected! Bailing out...");
Custom keys
Key/value pairs annotate crash reports with app state (current level, feature flags, etc.) and are filterable on the dashboard. Crashlytics supports up to 64 pairs, each up to 1 kB. Kotlin has a setCustomKeys builder DSL; Java uses typed setCustomKey overloads (String, boolean, int, long, float, double):
import com.google.firebase.crashlytics.setCustomKeys
Firebase.crashlytics.setCustomKeys {
key("my_string_key", "foo")
key("my_bool_key", true)
key("my_int_key", 1)
}
FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
crashlytics.setCustomKey("my_string_key", "foo");
crashlytics.setCustomKey("my_bool_key", true);
User identifiers
To work out which users a crash affects, attach an ID number, token, or hashed value that identifies the user without disclosing personal information (the Fabric-era setUserName/setUserEmail methods no longer exist):
Firebase.crashlytics.setUserId("user123456789")
FirebaseCrashlytics.getInstance().setUserId("user123456789");
Disable Crashlytics for debug builds
Crash reporting is enabled by default. To keep local-development crashes out of your dashboard, turn off automatic collection in AndroidManifest.xml and re-enable it at runtime only for release builds:
<application ...>
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="false" />
</application>
Firebase.crashlytics.setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG)
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG);
The runtime value persists across launches and overrides the manifest setting; see Enable opt-in reporting.
Historical note: Fabric Crashlytics
This page originally documented the Fabric-era setup: the console at fabric.io, the Fabric IDE plugin, the io.fabric.tools:gradle Gradle plugin served from maven.fabric.io, the com.crashlytics.sdk.android:crashlytics artifact, and Fabric.with(this, new Crashlytics()) initialization. All of that tooling was retired when the Fabric platform shut down on November 15, 2020, and none of it works today — see the Firebase blog post It’s Time to Upgrade to the New Firebase Crashlytics SDK! for the migration announcement.
Attribution
This guide was originally authored by Mateusz Utkała for the CodePath guides, and later rewritten for the Firebase Crashlytics SDK.