由于 Firebase 依赖性,应用程序在发布模式下崩溃

App crashes in Release mode due to Firebase dependency

我有一个应用程序,我最近注意到在没有安装 Google Play 服务 的设备上崩溃。经过一些调试后,我注意到原因是 Firebase。

这对我来说没问题,因为我认为 Firebase 需要 Google Play Services 到 运行。

问题是突然崩溃。我尝试检测 Google Play Service 是否在启动器 activity 中首先可用,以便我可以向用户显示正确的消息,但应用程序立即崩溃甚至没有在启动器 activity 或应用程序 class.

中执行代码

我该如何正确处理这个 Firebase 错误。我需要一种正确的方法来捕获错误或防止错误发生并显示正确的消息而不是崩溃。我看了很多类似的问题并尝试了解决方案,但这个案例看起来有点不同。

请注意,这仅在应用程序处于 发布 模式时发生。此外,您会注意到 logcat 突出显示了 SQLite,我在这个项目中没有使用 SQLite,我想也许 Firebase 正在引用它。

App level gradle:

plugins{
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-android-extensions'
    id 'kotlin-kapt'
    id 'realm-android'
    id 'com.google.gms.google-services'
    id 'com.google.firebase.crashlytics'
}

repositories {
    maven { url 'https://maven.google.com' }
}

android {
    compileSdkVersion 31
    defaultConfig {
        applicationId "com.myapp"
        minSdkVersion 19
        targetSdkVersion 31
        versionCode 14
        versionName "2.3.3"
        multiDexEnabled true
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
    }
    configurations {
        all {
            exclude module: 'httpclient'
            exclude module: 'commons-logging'
        }
    }
}

realm {
    syncEnabled = true
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31"
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
    implementation 'androidx.preference:preference-ktx:1.1.1'
    implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
    
    //if i remove the firebase dependencies, everything runs smoothly
    implementation 'com.google.firebase:firebase-core:20.0.0'
    implementation 'com.google.firebase:firebase-crashlytics:18.2.4'
    implementation 'com.google.firebase:firebase-analytics:20.0.0'
    implementation 'com.google.firebase:firebase-messaging:23.0.0'
    
    implementation 'com.google.code.gson:gson:2.8.7'
    implementation 'com.android.support:multidex:1.0.3'
    implementation 'com.google.android.gms:play-services-maps:18.0.0'
    implementation "com.squareup.retrofit2:retrofit:2.9.0"
    implementation "com.squareup.retrofit2:adapter-rxjava:2.9.0"
    implementation "com.squareup.retrofit2:converter-gson:2.9.0"

    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

Project level gradle:

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

buildscript {
    ext.kotlin_version = '1.5.31'
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
        maven { url 'https://plugins.gradle.org/m2/'}
       // jcenter() //for now(31Jul2021) Realm depends on this, will remove when Realm has moved - maybe to mavenCentral
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.gms:google-services:4.3.10'
        classpath "io.realm:realm-gradle-plugin:10.8.0"
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.0'
    }
}
allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

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

Logcat:

2021-11-02 23:15:31.406 17886-17886/com.myapp I/FirebaseApp: Device unlocked: initializing all Firebase APIs for app [DEFAULT]
    2021-11-02 23:15:31.459 17886-17900/com.myapp E/SQLiteLog: (1) table log_event_dropped already exists
    2021-11-02 23:15:31.459 17886-17886/com.myapp I/FirebaseCrashlytics: Initializing Firebase Crashlytics 18.2.4 for com.myapp
    2021-11-02 23:15:31.466 17886-17900/com.myapp E/TransportRuntime.Executor: Background execution failure.
        android.database.sqlite.SQLiteException: table log_event_dropped already exists (code 1): , while compiling: CREATE TABLE log_event_dropped (log_source VARCHAR(45) NOT NULL,reason INTEGER NOT NULL,events_dropped_count BIGINT NOT NULL,PRIMARY KEY(log_source, reason))
            at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
            at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:887)
            at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:498)
            at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
            at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
            at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
            at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1674)
            at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1605)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.k(SourceFile:1)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.e(SourceFile)
            at w20.upgrade(SourceFile)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.m(SourceFile:2)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.onUpgrade(SourceFile:2)
            at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:256)
            at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
            at g20.a(SourceFile)
            at com.google.android.datatransport.runtime.scheduling.persistence.SQLiteEventStore.r0(SourceFile:2)
            at com.google.android.datatransport.runtime.scheduling.persistence.SQLiteEventStore.E(SourceFile:3)
            at com.google.android.datatransport.runtime.scheduling.persistence.SQLiteEventStore.runCriticalSection(SourceFile:1)
            at com.google.android.datatransport.runtime.scheduling.jobscheduling.WorkInitializer.d(SourceFile:1)
            at com.google.android.datatransport.runtime.scheduling.jobscheduling.WorkInitializer.b(SourceFile)
            at le0.run(SourceFile)
            at q20$a.run(SourceFile:1)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
            at java.lang.Thread.run(Thread.java:818)
    2021-11-02 23:15:31.482 17886-17906/com.myapp E/FirebaseMessaging: Google Play services missing or without correct permission.
    2021-11-02 23:15:31.492 17886-17907/com.myapp E/ActivityThread: Failed to find provider info for com.google.android.gms.chimera
    2021-11-02 23:15:31.493 17886-17907/com.myapp W/DynamiteModule: Failed to retrieve remote module version.
    2021-11-02 23:15:31.500 17886-17907/com.myapp W/GooglePlayServicesUtil: Google Play Store is missing.
    2021-11-02 23:15:31.500 17886-17907/com.myapp I/DynamiteModule: Considering local module com.google.android.gms.measurement.dynamite:55 and remote module com.google.android.gms.measurement.dynamite:0
    2021-11-02 23:15:31.500 17886-17907/com.myapp I/DynamiteModule: Selected local version of com.google.android.gms.measurement.dynamite
    2021-11-02 23:15:31.501 17886-17907/com.myapp W/GooglePlayServicesUtil: Google Play Store is missing.
    2021-11-02 23:15:31.579 17886-17886/com.myapp I/FirebaseInitProvider: FirebaseApp initialization successful
    2021-11-02 23:15:31.590 17886-17886/com.myapp D/WM-WrkMgrInitializer: Initializing WorkManager with default configuration.
    2021-11-02 23:15:31.609 17886-17913/com.myapp V/FA: App measurement enabled for app package, google app id: com.myapp, 1:483778118943:android:c6a45e2f9497b6ac
    2021-11-02 23:15:31.610 17886-17913/com.myapp I/FA: App measurement initialized, version: 46000
    2021-11-02 23:15:31.610 17886-17913/com.myapp I/FA: To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
    2021-11-02 23:15:31.610 17886-17913/com.myapp I/FA: To enable faster debug mode event logging run:
          adb shell setprop debug.firebase.analytics.app com.myapp
    2021-11-02 23:15:31.610 17886-17913/com.myapp D/FA: Debug-level message logging enabled
    2021-11-02 23:15:31.669 17886-17886/com.myapp W/GooglePlayServicesUtil: Google Play Store is missing.
    2021-11-02 23:15:31.677 17886-17913/com.myapp V/FA: Checking service availability
    2021-11-02 23:15:31.679 17886-17913/com.myapp W/GooglePlayServicesUtil: Google Play Store is missing.
    2021-11-02 23:15:31.679 17886-17913/com.myapp W/FA: Service invalid
    2021-11-02 23:15:31.681 17886-17913/com.myapp V/FA: Using local app measurement service
    2021-11-02 23:15:31.706 17886-17913/com.myapp V/FA: Connection attempt already in progress
    2021-11-02 23:15:31.721 17886-17886/com.myapp E/ResourceType: Style contains key with bad entry: 0x0101056c
    2021-11-02 23:15:31.722 17886-17913/com.myapp V/FA: Connection attempt already in progress
    2021-11-02 23:15:31.736 17886-17907/com.myapp V/FA: onActivityCreated
    2021-11-02 23:15:31.857 17886-17913/com.myapp V/FA: Activity resumed, time: 67518553
    2021-11-02 23:15:31.865 17886-17913/com.myapp I/FA: Tag Manager is not found and thus will not be used
    2021-11-02 23:15:31.869 17886-17924/com.myapp D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
    2021-11-02 23:15:31.869 17886-17913/com.myapp W/GooglePlayServicesUtil: Google Play services is missing.
    2021-11-02 23:15:31.879 17886-17886/com.myapp V/FA: Local AppMeasurementService is starting up
    2021-11-02 23:15:31.895 17886-17913/com.myapp V/FA: Connection attempt already in progress
    2021-11-02 23:15:31.895 17886-17913/com.myapp V/FA: Connection attempt already in progress
    2021-11-02 23:15:31.921 17886-17924/com.myapp I/OpenGLRenderer: Initialized EGL, version 1.4
    2021-11-02 23:15:31.921 17886-17924/com.myapp W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
    2021-11-02 23:15:31.925 17886-17924/com.myapp D/EGL_emulation: eglCreateContext: 0x7ff0504fa320: maj 3 min 0 rcv 3
    2021-11-02 23:15:31.925 17886-17913/com.myapp V/FA: Upload scheduled in approximately ms: 2087017
    2021-11-02 23:15:31.926 17886-17913/com.myapp V/FA: Unscheduling upload
    2021-11-02 23:15:31.927 17886-17913/com.myapp V/FA: Scheduling upload, millis: 2087017
    2021-11-02 23:15:31.928 17886-17924/com.myapp D/EGL_emulation: eglMakeCurrent: 0x7ff0504fa320: ver 3 0 (tinfo 0x7ff05d016b40)
    2021-11-02 23:15:31.929 17886-17924/com.myapp E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008cdf
    2021-11-02 23:15:31.929 17886-17924/com.myapp E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008824
    2021-11-02 23:15:31.942 17886-17924/com.myapp D/EGL_emulation: eglMakeCurrent: 0x7ff0504fa320: ver 3 0 (tinfo 0x7ff05d016b40)
    2021-11-02 23:15:31.952 17886-17886/com.myapp V/FA: Bound to IMeasurementService interface
    2021-11-02 23:15:31.953 17886-17913/com.myapp V/FA: Connected to service
    2021-11-02 23:15:31.954 17886-17913/com.myapp V/FA: Processing queued up service tasks: 5
    2021-11-02 23:15:31.956 17886-17913/com.myapp V/FA: Storage concurrent access okay
    2021-11-02 23:15:31.971 17886-17913/com.myapp V/FA: Parsed config. version, gmp_app_id: 1630707713501066, 1:483778118943:android:c6a45e2f9497b6ac
    2021-11-02 23:15:31.975 17886-17913/com.myapp D/FA: Unable to get advertising id: com.google.android.gms.common.GooglePlayServicesNotAvailableException: com.google.android.gms.measurement.internal.zzjp.b(SourceFile:12)
    2021-11-02 23:15:32.027 17886-17913/com.myapp V/FA: Logging event: origin=auto,name=screen_view(_vs),params=Bundle[{ga_event_origin(_o)=auto, ga_screen_class(_sc)=SplashActivity, ga_screen_id(_si)=-5424791619731338053}]
    2021-11-02 23:15:32.029 17886-17913/com.myapp A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x25ff70 in tid 17913 (Measurement Wor)
    2021-11-02 23:15:32.119 17886-17900/com.myapp E/SQLiteLog: (1) table log_event_dropped already exists
    2021-11-02 23:15:32.119 17886-17900/com.myapp W/TransportRuntime: Error scheduling event table log_event_dropped already exists (code 1): , while compiling: CREATE TABLE log_event_dropped (log_source VARCHAR(45) NOT NULL,reason INTEGER NOT NULL,events_dropped_count BIGINT NOT NULL,PRIMARY KEY(log_source, reason))
    2021-11-02 23:15:32.120 17886-17908/com.myapp W/FirebaseCrashlytics: Crashlytics report could not be enqueued to DataTransport
        android.database.sqlite.SQLiteException: table log_event_dropped already exists (code 1): , while compiling: CREATE TABLE log_event_dropped (log_source VARCHAR(45) NOT NULL,reason INTEGER NOT NULL,events_dropped_count BIGINT NOT NULL,PRIMARY KEY(log_source, reason))
            at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
            at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:887)
            at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:498)
            at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
            at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
            at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
            at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1674)
            at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1605)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.k(SourceFile:1)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.e(SourceFile)
            at w20.upgrade(SourceFile)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.m(SourceFile:2)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.onUpgrade(SourceFile:2)
            at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:256)
            at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
            at g20.a(SourceFile)
            at com.google.android.datatransport.runtime.scheduling.persistence.SQLiteEventStore.r0(SourceFile:2)
            at com.google.android.datatransport.runtime.scheduling.persistence.SQLiteEventStore.E(SourceFile:3)
            at com.google.android.datatransport.runtime.scheduling.persistence.SQLiteEventStore.runCriticalSection(SourceFile:1)
            at com.google.android.datatransport.runtime.scheduling.DefaultScheduler.d(SourceFile:8)
            at com.google.android.datatransport.runtime.scheduling.DefaultScheduler.a(SourceFile)
            at fd.run(SourceFile)
            at q20$a.run(SourceFile:1)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
            at java.lang.Thread.run(Thread.java:818)
    2021-11-02 23:15:32.124 17886-17900/com.myapp E/SQLiteLog: (1) table log_event_dropped already exists
    2021-11-02 23:15:32.124 17886-17900/com.myapp W/TransportRuntime: Error scheduling event table log_event_dropped already exists (code 1): , while compiling: CREATE TABLE log_event_dropped (log_source VARCHAR(45) NOT NULL,reason INTEGER NOT NULL,events_dropped_count BIGINT NOT NULL,PRIMARY KEY(log_source, reason))
    2021-11-02 23:15:32.125 17886-17908/com.myapp W/FirebaseCrashlytics: Crashlytics report could not be enqueued to DataTransport
        android.database.sqlite.SQLiteException: table log_event_dropped already exists (code 1): , while compiling: CREATE TABLE log_event_dropped (log_source VARCHAR(45) NOT NULL,reason INTEGER NOT NULL,events_dropped_count BIGINT NOT NULL,PRIMARY KEY(log_source, reason))
            at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
            at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:887)
            at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:498)
            at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
            at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
            at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
            at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1674)
            at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1605)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.k(SourceFile:1)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.e(SourceFile)
            at w20.upgrade(SourceFile)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.m(SourceFile:2)
            at com.google.android.datatransport.runtime.scheduling.persistence.SchemaManager.onUpgrade(SourceFile:2)
            at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:256)
            at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
            at g20.a(SourceFile)
            at com.google.android.datatransport.runtime.scheduling.persistence.SQLiteEventStore.r0(SourceFile:2)
            at com.google.android.datatransport.runtime.scheduling.persistence.SQLiteEventStore.E(SourceFile:3)
            at com.google.android.datatransport.runtime.scheduling.persistence.SQLiteEventStore.runCriticalSection(SourceFile:1)
            at com.google.android.datatransport.runtime.scheduling.DefaultScheduler.d(SourceFile:8)
            at com.google.android.datatransport.runtime.scheduling.DefaultScheduler.a(SourceFile)
            at fd.run(SourceFile)
            at q20$a.run(SourceFile:1)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
            at java.lang.Thread.run(Thread.java:818)

我终于想出了如何解决这个问题。

FirebaseCrashlytics 甚至在应用程序 class 执行之前就进行了初始化,因此在没有 Google Play 服务的设备上处于发布模式时它会立即崩溃。正确处理此问题的最佳方法是通过在 Android 清单中禁用分析收集来禁用 FirebaseCrashlytics 在 运行 应用程序时立即尝试收集任何分析数据:

 <meta-data
       android:name="firebase_analytics_collection_enabled"
       android:value="false" />

然后在应用程序 class 中,我们可以检查 Google 播放服务是否可用。如果是这样,我们可以继续启用 Firebase 分析:

class MyApp : Application(){
    override fun onCreate() {
        super.onCreate()
        if(isGooglePlayServicesAvailable()){

  FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(true)
        }else{
           //show user proper error
        }
   }
    
    private fun isGooglePlayServicesAvailable(): Boolean {
        val googleApiAvailability = GoogleApiAvailability.getInstance()
        val status = googleApiAvailability.isGooglePlayServicesAvailable(this)
        if (status != ConnectionResult.SUCCESS) {
            return false
        }
        return true
    }
    
}