Firebase Crashlytics crash reports only appearing when app runs in Pre-release testing

Viewed 44

I have followed and triple-verified all of the setup steps for adding firebase & crashlytics to my app here: https://firebase.google.com/docs/android/setup?hl=en and here: https://firebase.google.com/docs/crashlytics/get-started?authuser=0&platform=android, verified that the google-services.json is correct (actually re-downloaded it for comparison, and it works for Firebase messaging). Enabled Analytics sharing. Crashlytics enabled for my app on Firebase console. Some json reports do get logged as uploaded at runtime (not crashes) with a 204 result, but on startup, the app gets an error "E/FirebaseCrashlytics: Settings request failed. java.io.FileNotFoundException: https://firebase-settings.crashlytics.com/spi/v2/platforms/android/gmp/(snip)&build_version=99&display_version=2022.08.31.99 blah blah blah" and then when I click on my "TEST CRASH" button, I get another error " E/FirebaseCrashlytics: Cannot send reports. Timed out while fetching settings.".

The thing is, the crash reports DO appear for crashes that occur during the Google Play Pre-Release testing upon upload to Google Play (closed testing), including for the "CRASH TEST" button, and then I get crash-free users, logs, stack trace, the whole thing. Because this part is working, it would appear that my setup is correct.

I have Proton VPN installed on the device, but have disabled it during testing. It does not seem to matter.

NOTE: I cannot get the crash to upload whether the app was subsequently downloaded (beta) from Google Play or whether I compiled it, debug or release, in order to run it with Android Studio with USB debugging to the same device (but I have to uninstall one to install the other, and only the downloaded one has the option to "Report" the crash -- I don't know if the crash would ever be uploaded if I don't choose Report, but I have never seen a reported crash, in the Play Console, Firebase, or anywhere else.)

Does anyone know how I can get crashes to be reported to Crashlytics outside of Pre-release testing? Are there any prerequisites like "app has to have been uploaded with the same version" or "no VPN allowed" or "'Report' must be selected in popup dialog on device after the crash" or "display version string must not contain spaces" or anything else? (From some things I have read even on the docs, it appeared I should be able to be testing a local build and get crash reports.)

I am using the latest "Chipmunk" Studio. I just updated to the latest firebase BOM.

From my project-level build.gradle:

buildscript {
    repositories {
        google()
        mavenCentral()
        maven {url "https://plugins.gradle.org/m2/" }
        maven { url "https://jitpack.io" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.2.2'
        //classpath 'com.google.android.gms:oss-licenses-plugin:0.9.5'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        //classpath 'com.github.jk1:gradle-license-report:1.9'
        classpath 'com.github.jk1:gradle-license-report:2.0'

        classpath 'com.google.gms:google-services:4.3.13'
        // Add the Crashlytics Gradle plugin
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.1'
    }
} ...

From my module-level build.gradle:

plugins {
    id 'com.android.application'
    id 'com.google.gms.google-services'
    id 'com.google.firebase.crashlytics'
}
...
    repositories {
        maven { url "https://jitpack.io" }
        mavenCentral()
    }

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:30.4.0')  // Bill Of Materials
        implementation 'androidx.appcompat:appcompat:1.4.2' // this is last version compatible with Android sdk 31
        implementation 'com.google.code.gson:gson:2.8.6'
        implementation 'com.squareup.retrofit2:retrofit:2.9.0'
        implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
        implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
        implementation 'androidx.navigation:navigation-ui:2.5.1'
        implementation "androidx.lifecycle:lifecycle-process:2.5.1"
        implementation 'androidx.lifecycle:lifecycle-common-java8:2.5.1'
        implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
        implementation 'org.jetbrains:annotations:15.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
        implementation 'androidx.preference:preference:1.2.0'
        implementation 'androidx.biometric:biometric:1.1.0'
        implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
        implementation 'org.apache.commons:commons-math3:3.6.1'
        implementation 'com.github.drawers:SpinnerDatePicker:2.1.0'
        testImplementation 'junit:junit:4.13-beta-2'
        androidTestImplementation 'androidx.test:runner:1.4.0'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

        implementation 'ch.qos.logback:logback-classic:1.2.10'
        implementation 'ch.qos.logback:logback-core:1.2.10'
        implementation 'org.codehaus.janino:commons-compiler:3.1.6'

        // for in-app purchases (data service subscription)
        implementation 'com.android.billingclient:billing:5.0.0'

        // for message broadcasting, diagnostics & analytics
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-analytics'
        implementation 'com.google.firebase:firebase-crashlytics'
        implementation 'com.google.firebase:firebase-messaging'
    }

In my main activity:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 ...
        // Obtain the FirebaseAnalytics instance.
        mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
...

            // TODO remove in production
            addTestCrashButtonForCrashlytics();
...
    }

    private void addTestCrashButtonForCrashlytics() {
        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
            }
        });

My thanks in advance for anyone who can help me figure this out.

1 Answers

Son of a ...! After DAYS on this problem, I just found the answer - the issue is, actually, that the display version had spaces in it. So, in the module level build.gradle, I had a descriptive versionName which explains in Google Play the latest summary of changes:

        versionName "2022.08.31.99 Blah, blah blah"

, which looked suspicious in the error "E/FirebaseCrashlytics: Settings request failed. java.io.FileNotFoundException: https://firebase-settings.crashlytics.com/spi/v2/platforms/android/gmp/(snip)&build_version=99&display_version=2022.08.31.99 blah blah blah", since URLs can't have spaces - so I tried changing it to just:

        versionName "2022.08.31.99"

I recompiled it and ran it over USB on the phone, tapped the test crash button and got a crash report almost immediately. Backed it out, the problem occurs, put it back, it's working! Hope this helps someone else!

By the way, this was working using a local debug build running over USB. Furthermore, it does not have to match an uploaded version in Google Play - I subsequently incremented it and it still reported a crash. It does seem to have an issue over VPN (it might be the particular server, or maybe just not allowed on VPN.) These were crashes that automatically uploaded to Crashlytics - I did not have to choose "Report" on a popup, and actually, could not because they were local builds, which as I mentioned earlier, don't give that option.

Related