Crash with ProGuard and Firebase Crashlytics

冷暖自知 提交于 2020-04-16 05:20:21

问题


Expected

It is expected for the release version of the Android app's build to run successfully when enabling minifyEnabled and shrinkResources per the Android documentation, Crashlytics, and Proguard.

The code for this issue may be found in the open-sourced GitHub repository for Coinverse.

Observed

  • The release version of the app crashes immediately when opened after being downloaded from Google Play. This appears to be due to Crashlytics failing to initialize.

  • Without minifyEnabled and shrinkResources the app runs as expected in production, and the app size goes from ~4mb to ~10mb.

  • The error log suggests it is an issue with Firebase compatibility and recommends this StackOverflow post. - What ProGuard configuration do I need for Firebase on Android?

  • There is a similar issue with ProGuard - transformClassesAndResourcesWithProguardForRelease FAILED.

Error

Summary

Crashlytics Core: Failed to execute task

Details

2020-04-13 22:57:04.750 25234-25234/? E/app.coinverse: Unknown bits set in runtime_flags: 0x8000
2020-04-13 22:57:06.310 25234-25234/app.coinverse E/AndroidRuntime: FATAL EXCEPTION: main
    Process: app.coinverse, PID: 25234
    java.lang.RuntimeException: Unable to create application app.coinverse.App: java.lang.RuntimeException: Failed to instantiate AndroidPlatform class.  Using ProGuard?  See http://stackoverflow.com/questions/26273929/what-proguard-configuration-do-i-need-for-firebase-on-android
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6465)
        at android.app.ActivityThread.access$1300(ActivityThread.java:219)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.RuntimeException: Failed to instantiate AndroidPlatform class.  Using ProGuard?  See http://stackoverflow.com/questions/26273929/what-proguard-configuration-do-i-need-for-firebase-on-android
        at e.e.a.d.a.a(:69)
        at e.e.a.a.a(:974)
        at d.a.k.a.<init>(:42)
        at d.a.k.b.a(:29)
        at d.a.k.b.get(:21)
        at d.a.k.b.get(:8)
        at f.b.b.get(:47)
        at d.a.i.d.a(:107)
        at app.coinverse.App.onCreate(:18)
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1189)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6460)
        at android.app.ActivityThread.access$1300(ActivityThread.java:219) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
     Caused by: java.lang.NoSuchMethodException: e.e.a.c.a.<init> [class android.content.Context]
        at java.lang.Class.getConstructor0(Class.java:2332)
        at java.lang.Class.getConstructor(Class.java:1728)
        at e.e.a.d.a.a(:62)
        at e.e.a.a.a(:974) 
        at d.a.k.a.<init>(:42) 
        at d.a.k.b.a(:29) 
        at d.a.k.b.get(:21) 
        at d.a.k.b.get(:8) 
        at f.b.b.get(:47) 
        at d.a.i.d.a(:107) 
        at app.coinverse.App.onCreate(:18) 
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1189) 
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6460) 
        at android.app.ActivityThread.access$1300(ActivityThread.java:219) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
2020-04-13 22:57:10.312 25234-25234/app.coinverse E/CrashlyticsCore: Failed to execute task.
    java.util.concurrent.TimeoutException
        at java.util.concurrent.FutureTask.get(FutureTask.java:206)
        at e.b.a.e.u.b(:41)
        at e.b.a.e.k1.a(:321)
        at e.b.a.e.t0.a(:301)
        at e.b.a.e.y1.uncaughtException(:42)
        at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1073)
        at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
        at java.lang.Thread.dispatchUncaughtException(Thread.java:2187)

Implementation

build.gradle (:app)

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'androidx.navigation.safeargs'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'io.fabric'
apply plugin: 'de.mannodermaus.android-junit5'

android {
    compileSdkVersion 29
    defaultConfig {
        applicationId "app.coinverse"
        minSdkVersion 24
        targetSdkVersion 29
        versionCode 57
        versionName "0.57"
        kotlinOptions { jvmTarget = '1.8' }
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }
    sourceSets { androidTest.assets.srcDirs += files("$projectDir/schemas".toString()) }

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile(
                    'proguard-android-optimize.txt'),
                    'proguard-rules.pro',
                    'proguard.cfg'
        }
        debug {
            applicationIdSuffix ".staging"
            debuggable true
        }
        open {
            initWith debug
            applicationIdSuffix ".open"
        }
    }
    compileOptions { targetCompatibility JavaVersion.VERSION_1_8 }

    dataBinding.enabled = true

    testOptions { unitTests.includeAndroidResources = true }
}

dependencies {
    def lifecycle_version = '2.2.0'
    def lifecycle_test_version = '2.1.0'
    def nav_version = '2.2.1'
    def play_services_version = '17.0.0'
    def exoplayer_version = '2.11.1'
    def room_version = '2.2.5'
    def glide_version = '4.11.0'
    def mopub_version = '5.12.0'
    def junit_version = '5.5.1'
    def test_rules_core_version = '1.2.0'
    def fragment_version = '1.2.4'

    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.google.dagger:dagger:2.27'
    kapt 'com.google.dagger:dagger-compiler:2.27'
    implementation "androidx.fragment:fragment-ktx:$fragment_version"
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    implementation "androidx.room:room-ktx:$room_version"
    implementation "androidx.paging:paging-runtime-ktx:2.1.2"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.1.1'
    implementation "com.google.android.gms:play-services-auth:18.0.0"
    implementation "com.google.android.gms:play-services-location:$play_services_version"
    implementation 'com.firebase:firebase-client-android:2.5.2'
    implementation 'com.google.firebase:firebase-analytics:17.3.0'
    implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
    implementation 'com.google.firebase:firebase-perf:19.0.5'
    implementation 'com.google.firebase:firebase-firestore-ktx:21.4.0'
    implementation 'com.google.firebase:firebase-functions:19.0.2'
    implementation 'com.google.firebase:firebase-auth:19.3.0'
    implementation 'com.firebaseui:firebase-ui-firestore:4.2.0'
    implementation 'com.firebaseui:firebase-ui-auth:4.2.1'
    implementation 'com.google.firebase:firebase-storage:19.1.1'
    implementation 'com.google.firebase:firebase-inappmessaging-display:19.0.4'
    implementation 'com.google.firebase:firebase-config:19.1.3'
    implementation 'com.jjoe64:graphview:4.2.2'
    implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version"
    implementation "com.google.android.exoplayer:exoplayer-ui:$exoplayer_version"
    implementation files('libs/YouTubeAndroidPlayerApi.jar')
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
    implementation "com.github.bumptech.glide:glide:$glide_version"
    kapt "com.github.bumptech.glide:compiler:$glide_version"
    implementation("com.mopub:mopub-sdk-native-static:$mopub_version") { transitive = true }
    implementation("com.mopub:mopub-sdk-native-video:$mopub_version") { transitive = true }
    implementation 'com.facebook.android:audience-network-sdk:5.8.0'
    implementation 'com.mopub.mediation:facebookaudiencenetwork:5.8.0.0'
    implementation 'com.flurry.android:ads:12.3.0'
    implementation 'com.flurry.android:analytics:12.3.0'
    implementation 'com.mopub.mediation:flurry:12.0.3.1'

    // Testing

    // Local Unit
    testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version"
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_version"
    testImplementation "org.junit.jupiter:junit-jupiter-params:$junit_version"
    testImplementation "io.mockk:mockk:1.9.3"
    testImplementation 'org.assertj:assertj-core:3.13.2'
    debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
    testImplementation "androidx.arch.core:core-testing:$lifecycle_test_version"
    testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.2"

    // AndroidX - JVM
    testImplementation "androidx.test:core-ktx:1.2.0"
    testImplementation "androidx.test.ext:junit-ktx:1.1.1"
    testImplementation "androidx.test:rules:$test_rules_core_version"
    testImplementation "androidx.test:core:$test_rules_core_version"
}

build.gradle (android)

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.3.71'
    repositories {
        google()
        jcenter()
        mavenCentral()
        maven { url 'https://maven.google.com' }
        maven { url 'https://maven.fabric.io/public' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.gms:google-services:4.3.3'
        classpath 'com.google.firebase:perf-plugin:1.3.1'
        classpath 'io.fabric.tools:gradle:1.31.2'
        classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
        classpath "de.mannodermaus.gradle.plugins:android-junit5:1.5.1.0"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://maven.google.com/' }
        maven { url "https://s3.amazonaws.com/moat-sdk-builds" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

App.kt

The release version of the app is crashing when attempting to initialize the FirebaseHelper.kt class.

class App : Application() {
    val component = DaggerComponent.builder()
            .utilsModule(UtilsModule(this))
            .build()

    override fun onCreate() {
        super.onCreate()
        // Here is where the crash occurs.
        component.firebaseHelper()
        MoPub.initializeSdk(this, SdkConfiguration.Builder(AD_UNIT_ID).build(), initSdkListener())
    }

    private fun initSdkListener() = SdkInitializationListener { /* MoPub SDK initialized.*/ }
}

FirebaseHelper.kt

@Singleton
class FirebaseHelper @Inject constructor(context: Context) {
    private val LOG_TAG = FirebaseHelper::class.java.simpleName

    init {
        if (BuildConfig.BUILD_TYPE == open.name) {
            var openSharedStatus = false
            FirebaseApp.getApps(context).map { app ->
                if (app.name.equals(open.name))
                    openSharedStatus = true
            }
            if (!openSharedStatus)
                FirebaseApp.initializeApp(
                        context,
                        FirebaseOptions.Builder()
                                .setApplicationId(APP_ID_OPEN_SHARED)
                                .setApiKey(APP_API_KEY_OPEN_SHARED)
                                .setDatabaseUrl(DATABASE_URL_OPEN_SHARED)
                                .setProjectId(PROJECT_ID_OPEN_SHARED)
                                .setStorageBucket(STORAGE_BUCKET_OPEN_SHARED)
                                .build(),
                        open.name)
        }
        Firebase.setAndroidContext(context)
        initializeRemoteConfig()
    }

    private fun initializeRemoteConfig() {
        val firebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
        firebaseRemoteConfig.setConfigSettingsAsync(FirebaseRemoteConfigSettings.Builder().build())
        firebaseRemoteConfig.setDefaultsAsync(R.xml.remote_config_defaults)
        val cacheExpiration = 3600L
        try {
            firebaseRemoteConfig.fetch(cacheExpiration)
            firebaseRemoteConfig.fetchAndActivate()
        } catch (exception: FirebaseRemoteConfigException) {
            Crashlytics.log(Log.ERROR, LOG_TAG, "initializeRemoteConfig: ${exception.localizedMessage}")
        }
    }
}

Attempted Solutions

1 - Explicitly enabling Crashlytics in build.gradle

buildTypes {
    release {
        ext.enableCrashlytics = true
        ...
    }
    ...
}

2 - Adding proguard.cfg rules for Firebase.

-keep class com.firebase.** { *; }
-keep class org.apache.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class javax.servlet.** { *; }
-keepnames class org.ietf.jgss.** { *; }
-dontwarn org.w3c.dom.**
-dontwarn org.joda.time.**
-dontwarn org.shaded.apache.**
-dontwarn org.ietf.jgss.**

# Only necessary if you downloaded the SDK jar directly instead of from maven.
-keep class com.shaded.fasterxml.jackson.** { *; }

3 - Adding proguard.cfg rules for the app model classes being returned and posted to Firestore's database.

# Add this global rule
-keepattributes Signature

-keepclassmembers class app.coinverse.analytics.models.** {
  *;
}
-keepclassmembers class app.coinverse.feed.models.** {
  *;
}
-keepclassmembers class app.coinverse.priceGraph.models.** {
  *;
}
-keepclassmembers class app.coinverse.user.models.** {
  *;
}
-keepclassmembers class app.coinverse.utils.** {
  *;
}

4 - Adding pro-guard-rules-release.txt

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-release.txt'
testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-test.txt'

来源:https://stackoverflow.com/questions/57010884/crash-with-proguard-and-firebase-crashlytics

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!