You can now set up Crashlytics in your app by using the new official Firebase Crashlytics SDK, which offers improved APIs that are more consistent with other Firebase products and more intuitive to use. This guide describes how to upgrade to the new SDK from the Fabric Crashlytics SDK. It describes the changes that come with the new APIs, the reason for the changes, and how to update your code, if required.
If you recently migrated your app from Fabric, review how upgrading to the Firebase Crashlytics SDK affects your crash analytics data.
Before you begin
The Firebase Crashlytics SDK uses AndroidX as a dependency, so if your app uses older versions of the App Support Library, first migrate your app to AndroidX.
Step 1: Add a Firebase configuration file
Add the Firebase Android configuration file to your app:
- Open your Project Settings. In the Your apps card, select the package name of the app for which you need a config file.
-
Click Download google-services.json to obtain your Firebase Android
config file.
- You can download your Firebase Android config file again at any time.
- Make sure the config file is not appended with additional
characters, like
(2)
.
- Move your config file into the module (app-level) directory of your app.
Step 2: Add the Firebase Crashlytics SDK
-
In your app's root-level (project-level)
build.gradle
:- Replace Fabric's Maven repository with Google's Maven repository.
- Replace the Fabric Gradle plugin with the Firebase Crashlytics Gradle plugin. If you're using Android Studio 4.1 Canary, be sure to add the Crashlytics Gradle plugin version 2.0.0 or later.
buildscript { // ... repositories { // ... // Remove Fabric's Maven repository.
maven { url 'https://maven.fabric.io/public' }// Add Google's Maven repository (if it's not there already). google() } dependencies { // .. // Add the Google Services Gradle plugin (if it's not there already). classpath 'com.google.gms:google-services:4.3.4' // Remove the Fabric Gradle plugin.classpath 'io.fabric.tools:gradle:1.31.2'// Add the Crashlytics Gradle plugin (use v2.0.0+ if you built // your app with Android Studio 4.1). classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1' } } -
In your app-level
build.gradle
, replace the Fabric plugin with the Firebase Crashlytics plugin:apply plugin: 'com.android.application' // Apply the Google Services plugin (if it's not there already). apply plugin: 'com.google.gms.google-services' // Remove the Fabric plugin.
apply plugin: 'io.fabric'// Add the Firebase Crashlytics plugin. apply plugin: 'com.google.firebase.crashlytics' -
Finally, add the Firebase Crashlytics SDK. In your app-level
build.gradle
, replace the legacy Fabric Crashlytics SDK with the new Firebase Crashlytics SDK. Make sure you add version 17.0.0 or later (beginning November 15, 2020, this is required for your crash reports to appear in the Firebase console).dependencies { // Remove the Fabric Crashlytics SDK.
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'// Add the Firebase Crashlytics SDK. implementation 'com.google.firebase:firebase-crashlytics:17.3.0' // Recommended: Add the Google Analytics SDK. implementation 'com.google.firebase:firebase-analytics:18.0.1' }
Optional step: Set up NDK crash reporting
Firebase Crashlytics offers crash reporting for apps built using the Android Native Development Kit (NDK). Note that the Crashlytics NDK v17.3.0+ requires the Crashlytics Gradle plugin v2.4.0+.
To detect and report native crashes:
- In your app-level
build.gradle
, replace the Fabric NDK dependency with the Firebase Crashlytics NDK dependency. Then, add the firebaseCrashlytics extension and make sure to enable thenativeSymbolUploadEnabled
flag. This allows your app to process and upload native symbols to Crashlytics so you can view properly-symbolicated stack traces in the Crashlytics dashboard.dependencies { // Remove the Fabric NDK dependency.
implementation 'com.crashlytics.sdk.android:crashlytics-ndk:2.1.1'// Add the Firebase Crashlytics NDK dependency. implementation 'com.google.firebase:firebase-crashlytics-ndk:17.3.0' } // ... android { // ... buildTypes { release { /* Add the firebaseCrashlytics extension (by default, * it's disabled to improve build speeds) and set * nativeSymbolUploadEnabled to true. */ firebaseCrashlytics { nativeSymbolUploadEnabled true } } } } // Remove this extension (it previously enabled Crashlytics NDK reporting in Fabric). crashlytics {enableNdk true} - Run the following NDK-specific Gradle tasks:
> ./gradlew app:assembleBUILD_VARIANT > ./gradlew app:uploadCrashlyticsSymbolFileBUILD_VARIANT
For more information about using Crashlytics for NDK crash reporting, see the Crashlytics NDK documentation.
Step 3: Update your code
Review the following SDK changes and make the appropriate updates to your code:
Crashlytics now rotates IDs based on Firebase installation IDs.
Crashlytics uses the Crashlytics Installation UUID to identify instances of your app and to associate your users' data with their devices. Previously, Crashlytics rotated your user's Installation UUID when the advertising ID of their device changed. Now, Crashlytics rotates the Installation UUID based on the user's Firebase installation ID (FID). For more information, visit Manage Firebase installation IDs.
Reason for change
Using FIDs is consistent with other Firebase SDKs.
The new package and classname for Crashlytics is com.google.firebase.crashlytics.FirebaseCrashlytics.
You can now invoke Crashlytics features using instance methods in the
FirebaseCrashlytics singleton instead of static functions in the
FirebaseCrashlytics class. The FirebaseCrashlytics singleton is globally
accessible via the getInstance()
static function.
Fabric SDK
Java
import com.crashlytics.android.Crashlytics; // ... // Operations on Crashlytics. Crashlytics.someAction()
Kotlin+KTX
import com.crashlytics.android.Crashlytics // ... // Operations on Crashlytics. Crashlytics.someAction()
Firebase Crashlytics SDK
Java
import com.google.firebase.crashlytics.FirebaseCrashlytics; // ... // Operations on FirebaseCrashlytics. FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance(); crashlytics.someAction();
Kotlin+KTX
import com.google.firebase.crashlytics.FirebaseCrashlytics // ... // Operations on FirebaseCrashlytics. val crashlytics = FirebaseCrashlytics.getInstance() crashlytics.someAction()
Reason for change
The new SDK's root package and entry point are now consistent with other Firebase SDKs. In addition, instance methods are easier to mock than static functions and create fewer testability challenges.
FirebaseCrashlytics no longer works with the Fabric SDK.
Now, Crashlytics starts up automatically using a
ContentProvider defined in the new Firebase Crashlytics SDK, which no longer
uses the Fabric API key. Crashlytics
now uses your app’s google-services.json
file to associate the app
with your Firebase project and retain your historic crash data.
If you have the Fabric API key (io.fabric.ApiKey
) declared in your
AndroidManifest.xml
file, remove it:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.your_app_package"> <application> <activity android:name=".MainActivity"/> <!-- Remove this line if it exists --> <meta-data android:name="io.fabric.ApiKey" android:value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" /> </application> </manifest>
By default, Crashlytics automatically collects and reports crashes for
all instances of your app, but you can choose to enable it
only for users who opt in. To turn off automatic crash reporting, in the
<application>
block of your AndroidManifest.xml
file, set
firebase_crashlytics_collection_enabled
to false
:
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="false" />
Reason for change
To be consistent with other Firebase SDKs, Crashlytics now starts up
automatically via a ContentProvider. Like with other SDKs, it now provides a
manifest flag to disable automatic data collection, which you can override at
any time using setCrashlyticsCollectionEnabled
. The method gives
you more control over your app's crash reporting behavior.
Crashlytics.log is now an instance method.
The new SDK no longer includes a static Crashlytics.log
method. To
add custom log messages, use the new instance method
crashlytics.log
instead. Note that the new method
no longer echoes to logcat (we recommend writing a wrapper if you want to keep
this behavior). For more information, visit
add custom log messages
.
Fabric SDK
Java
Crashlytics.log("my message"); Crashlytics.log( Log.ERROR, "TAG", "my message");
Kotlin+KTX
Crashlytics.log("my message") Crashlytics.log( Log.ERROR, "TAG", "my message")
Firebase Crashlytics SDK
Java
FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance(); crashlytics.log("my message"); // To log a message to a crash report, use the following syntax: crashlytics.log("E/TAG: my message");
Kotlin+KTX
val crashlytics = FirebaseCrashlytics.getInstance() crashlytics.log("my message") // To log a message to a crash report, use the following syntax: crashlytics.log("E/TAG: my message")
Reason for change
At your request, we have stopped echoing Crashlytics logs to logcat. Using instance methods also makes it easier to test your code.
setBool, setDouble, setFloat, and setInt, setLong, and setString are aggregated into setCustomKey.
We aggregated the custom key setters into the method setCustomKey
.
Previously, you could use the custom key setters to set key/value pairs to send
along with your crash report. Now, you can use setCustomKey(String,
value)
, which is overloaded to accept primitive and String types.
For more information, visit Add custom keys.
Fabric SDK
Java
Crashlytics.setBool("bool_key",true); Crashlytics.setDouble("double_key",42.0); Crashlytics.setFloat("float_key",42.0F); Crashlytics.setInt("int_key",42); Crashlytics.setLong("long_key",42L); Crashlytics.setString("str_key","str_value");
Kotlin+KTX
Crashlytics.setBool("bool_key",true) Crashlytics.setDouble("double_key",42.0) Crashlytics.setFloat("float_key",42.0F) Crashlytics.setInt("int_key",42) Crashlytics.setLong("long_key",42L) Crashlytics.setString("str_key","str_value")
Firebase Crashlytics SDK
Java
FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance(); crashlytics.setCustomKey("bool_key",true); crashlytics.setCustomKey("double_key",42.0); crashlytics.setCustomKey("float_key",42.0F); crashlytics.setCustomKey("int_key",42); crashlytics.setCustomKey("long_key",42L); crashlytics.setCustomKey("str_key","42");
Kotlin+KTX
FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance() crashlytics.setCustomKey("bool_key",true) crashlytics.setCustomKey("double_key",42.0) crashlytics.setCustomKey("float_key",42.0F) crashlytics.setCustomKey("int_key",42) crashlytics.setCustomKey("long_key",42L) crashlytics.setCustomKey("str_key","42")
Reason for change
The new method name is unique to Crashlytics and makes it clear that Crashlytics is not key-value compliant.
setUserIdentifier is now setUserId. setUserName and setUserEmail are removed.
Previously, you could set a name or email associated with a crash using
setUserName
and setUserEmail
, but these methods are
no longer defined. The new preferred method to set IDs for your users is to
use setUserId
. For more information, visit
Set user identifiers.
Fabric SDK
Java
Crashlytics.setUserIdentifier("myAppUserId"); Crashlytics.setUserEmail("abc@example.com"); Crashlytics.setUserName("John Doe");
Kotlin+KTX
Crashlytics.setUserIdentifier("myAppUserId") Crashlytics.setUserEmail("abc@example.com") Crashlytics.setUserName("John Doe")
Firebase Crashlytics SDK
Java
crashlytics.setUserId("myAppUserId");
Kotlin+KTX
crashlytics.setUserId("myAppUserId")
Reason for change
We adopted the method name setUserId
to be consistent with other
Firebase APIs and removed setUserName
and setUserEmail
to discourage logging PII through Crashlytics.
Crashlytics.logException(Throwable) is replaced by FirebaseCrashlytics.recordException(Throwable).
Crashlytics now also supports logging the built-in error and exception types for both Android and iOS.
Fabric SDK
Java
try { /* Code that can throw checked exceptions. */ // ... } catch (Exception e) { Crashlytics.logException(e); }
Kotlin+KTX
try { /* Code that can throw checked exceptions. */ // ... catch (e: Exception) { Crashlytics.logException(e) }
Firebase Crashlytics SDK
Java
try { /* Code that can throw checked exceptions. */ // ... } catch (Exception e) { FirebaseCrashlytics.getInstance().recordException(e); }
Kotlin+KTX
try { /* Code that can throw checked exceptions. */ // ... catch (e: Exception) { FirebaseCrashlytics.getInstance().recordException(e) }
Reason for change
The new method recordException(Throwable)
is more easily
distinguishable from log(String)
, which behaves differently. In
addition, we renamed the new API to be more consistent across platforms.
The CrashlyticsListener is replaced by didCrashOnPreviousExecution().
The CrashlyticsListener previously allowed Crashlytics to indicate when
a previous app session ends in a crash, which is useful for apps that display
post-crash messaging at relaunch. Now, its callback is replaced by the
synchronous API call didCrashOnPreviousExecution()
.
Fabric SDK
Java
CrashlyticsListener crashlyticsListener = new CrashlyticsListener() { @Override public void crashlyticsDidDetectCrashDuringPreviousExecution() { // ...App code to execute if a crash occurred during previous execution. } }; CrashlyticsCore crashlyticsCore = new CrashlyticsCore.Builder() .listener(crashlyticsListener) .build(); Crashlytics crashlytics = new Crashlytics.Builder().core(crashlyticsCore).build(); Fabric.with(getContext(), crashlytics);
Kotlin+KTX
val crashlyticsListener = CrashlyticsListener { // ...App code to execute if a crash occurred during previous execution. } val crashlyticsCore = CrashlyticsCore.Builder() .listener(crashlyticsListener) .build() val crashlytics = Crashlytics.Builder().core(crashlyticsCore).build() Fabric.with(getContext(), crashlytics)
Firebase Crashlytics SDK
Java
if (FirebaseCrashlytics.getInstance().didCrashOnPreviousExecution()) { // ...App code to execute if a crash occurred during previous execution. }
Kotlin+KTX
if (FirebaseCrashlytics.getInstance().didCrashOnPreviousExecution()) { // ...App code to execute if a crash occurred during previous execution. }
Reason for change
The new API is less verbose and less challenging to work with than the CrashlyticsListener because it requires neither boilerplate text nor a callback. Previously, the asynchronous callback didn't guarantee when the callback would be invoked.
The crash method is removed.
The new SDK no longer includes the crash method, which you could previously use
to validate your Crashlytics configuration by forcing a crash in your app.
Throw a RuntimeException
to force a crash.
Fabric SDK
Java
Crashlytics.getInstance().crash();
Kotlin+KTX
Crashlytics.getInstance().crash()
Firebase Crashlytics SDK
Java
throw new RuntimeException("Test Crash");
Kotlin+KTX
throw RuntimeException("Test Crash")
Reason for change
The new methods clearly specify whether your app's resulting crashes occurred during runtime or in the app's native SDK.
The Crashlytics Gradle plugin contains new flags.
The Gradle plugin continues to configure and execute Crashlytics-specific
Gradle tasks automatically. If your build requires invoking tasks from the
Crashlytics Gradle plugin, refer to the available Firebase Crashlytics
tasks by running ./gradlew app:tasks
. If your app uses an NDK, you
must explicitly invoke the
uploadCrashlyticsSymbolFile[BUILD_VARIANT]
Gradle task
to continue uploading native symbols to Crashlytics.
The Crashlytics-specific build flags ext.alwaysUpdateBuildId
and ext.enableCrashlytics
are no longer supported. Remove them from
your Gradle configuration if they exist. If your app uses a bytecode obfuscator
(e.g., R8 or Proguard) and you don't want to upload your build's mapping file to
Crashlytics, use the new mappingFileUploadEnabled
flag in the
firebaseCrashlytics
Gradle extension. When set to false,
Crashlytics cannot deobfuscate your app's stack traces.
For non-standard obfuscator configurations,
use the mappingFile
parameter to set a new location for your
mapping file. These flags can be used for defaultConfig, as well as for any
build type or flavor.
Firebase Crashlytics SDK
apply plugin: 'com.android.application' apply plugin: 'com.google.firebase.crashlytics' apply plugin: 'com.google.gms.google-services' android { // ... buildTypes { debug { minifyEnabled true firebaseCrashlytics { // If you don't need crash reporting for your debug build, // you can speed up your build by disabling mapping file uploading. mappingFileUploadEnabled false } } release { minifyEnabled true // When minifyEnabled is set to true, Crashlytics automatically // uploads mapping files because the plugin detects that obfuscation // is enabled. mappingFileUploadEnabled defaults to true if // minifyEnabled is true. } } }
Reason for change
We updated the Gradle tasks and configuration options to be more consistent with Gradle conventions.
Crashlytics can only use data collected by Google Analytics.
You can no longer collect data with Fabric Answers after upgrading to the Firebase Crashlytics SDK. To get metrics for crash-free users and breadcrumbs, switch over to using Google Analytics instead. Note that your historical Answers data cannot migrate to Firebase.
Visit Start using Google Analytics to learn how to add Google Analytics to your app. If you previously used Fabric Answers, find out how to convert your Answers events into Analytics events.
Reason for change
We now offer Google Analytics to help you get more insight into your crash data. With Analytics, you can continue gathering stats for your app in the Firebase console.
Next steps
Test your Crashlytics setup by forcing a crash in the Firebase console.
Customize your crash report setup by adding opt-in reporting, logs, keys, and tracking of non-fatal errors.
Add Google Analytics to your app. Combine the power of Google Analytics with Firebase Crashlytics to see crash-free user statistics in the Firebase console.