Search code examples
android-studiofirebasecrashlyticsandroid-proguardfirebase-crash-reporting

Stack trace deobfuscation: Android Studio with ProGuard and Crashlytics


How does the magic of stack trace deobfuscation works with Android Studio, ProGuard and Crashlytics?

Each app build generates an unique build id, and as I understand, it is generated even if versionCode and versionName of the app haven't changed:

<string name = "com.crashlytics.android.build_id">RANDOM_UUID</ string>

As I assuming, at build time, this build id, together with mapping.txt, is uploaded to the Crashlytics server. And, in turn, each crash report contains this build id. Thus, the Crashlytics server can find the correct mapping.txt, even for builds with the same versionCode and versionName.

But what if during the build I got temporary lost an Internet connection, and I wouldn't notice this? I've tried to make a build with the Internet turned off, and it was successful, no warnings, no errors. But I anticipated the build would fail, complaining that it couldn't upload mapping.txt and the build id to the Crashlytics server.

So, how Crashlytics plugin for Gradle does handles build without Internet?

And is assumption, that Crashlytics can distinguish builds with the same versionCode and versionName, is correct?

UPD. Before I got answer from Mike, I've also found insights on what's going on under the hood, by simply doing ./gradlew tasks --all in my projects root directory:

  • app:crashlyticsStoreDeobsRelease - Crashlytics target to be invoked after completing release builds. Cleans up Crashlytics-generated resource files. Caches and uploads deobfuscation files to Crashlytics servers.
  • app:crashlyticsUploadDeobsRelease - Uploads stored deobfuscation files to Crashlytics.
  • app:crashlyticsUploadDistributionDebug - Uploads an APK to Crashlytics for distribution.
  • app:crashlyticsUploadDistributionRelease - Uploads an APK to Crashlytics for distribution.
  • app:fabricGenerateResourcesDebug - Injects the build id used by the Fabric SDK.
  • app:fabricGenerateResourcesRelease - Injects the build id used by the Fabric SDK.

Solution

  • Mike from Fabric here. For builds that happen when there is no active network connection, we cache the mapping-build ID pair on the machine that ran the build. When you have a restored network connection, we upload the cached data.

    Yes, we can distinguish builds with the same versionCode and versionName because of the unique id per build. That's also why you have to be careful with it's generation :)