需要调用FirebaseApp.initializeApp()来初始化Firebase吗?

5
我将Firebase添加到我的Android项目中,以使用Firebase云消息传递。我按照文档的指示操作,但没有发现调用FirebaseApp.initializeApp()的任何说明。
我的应用程序工作正常,只有一次它崩溃并出现以下错误。
Caused by: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.my.app. Make sure to call FirebaseApp.initializeApp(Context) first.
at com.google.firebase.FirebaseApp.getInstance(Unknown Source)
at com.google.firebase.iid.FirebaseInstanceId.getInstance(Unknown Source)
at com.my.app.core.ApplicationEx.onCreate(ApplicationEx.java:79)

当我查找错误时,解决方法是在启动时调用FirebaseApp.initializeApp()

我想知道这是否真的必要,因为文档没有提到它,而且我的应用程序(大多数情况下)没有问题。

有人知道是否需要调用FirebaseApp.initializeApp(),还有什么其他原因可能会导致我上面提到的错误吗?

以下是我的build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.my.app"
        minSdkVersion 17
        targetSdkVersion 26
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
    }
    flavorDimensions "appType"
    productFlavors {
        passenger {
            dimension "appType"
            applicationId "com.my.app.passenger"
            versionCode 1
            versionName "1"
        }
        driver {
            dimension "appType"
            applicationId "com.my.app.driver"
            versionCode 1
            versionName "1"
        }
        admin {
            dimension "appType"
            applicationId "com.my.app.admin"
            versionCode 1
            versionName "1"
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            testCoverageEnabled true
        }
        packagingOptions {
            exclude 'META-INF/ASL2.0'
            exclude 'META-INF/LICENSE'
            exclude 'META-INF/NOTICE'
            exclude 'META-INF/NOTICE.txt'
            exclude 'META-INF/LICENSE.txt'
            exclude 'META-INF/MANIFEST.MF'
        }
    }
}

repositories {
    maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}

dependencies {
    implementation project(path: ':cards')
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "com.android.support:design:${supportVersion}"
    implementation "com.android.support:support-v4:${supportVersion}"
    implementation "com.android.support:appcompat-v7:${supportVersion}"
    implementation "com.android.support:cardview-v7:${supportVersion}"
    implementation "com.android.support:gridlayout-v7:${supportVersion}"
    implementation "com.google.android.gms:play-services-maps:${googlePlayServicesVersion}"
    implementation "com.google.android.gms:play-services-location:${googlePlayServicesVersion}"
    implementation "com.google.android.gms:play-services-places:${googlePlayServicesVersion}"
    implementation "com.google.android.gms:play-services-gcm:${googlePlayServicesVersion}"
    implementation "com.google.android.gms:play-services-ads:${googlePlayServicesVersion}"
    implementation "com.google.android.gms:play-services-auth:${googlePlayServicesVersion}"
    implementation 'com.google.maps:google-maps-services:0.2.5'
    implementation "com.google.firebase:firebase-messaging:${googlePlayServicesVersion}"
    implementation "com.loopj.android:android-async-http:${asyncHttpVersion}"
    implementation "com.android.support.test.espresso:espresso-idling-resource:${espressoVersion}"
    implementation 'com.android.support:multidex:1.0.2'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'org.slf4j:slf4j-api:1.7.25'
    implementation 'com.github.tony19:logback-android-core:1.1.1-6'
    implementation 'ch.acra:acra:4.9.2'
    implementation('com.github.tony19:logback-android-classic:1.1.1-6') {
        exclude group: 'com.google.android', module: 'android'      // workaround issue #73
    }
    testImplementation 'org.testng:testng:6.9.6'
    testImplementation 'org.mockito:mockito-core:1.10.19'
    testImplementation 'org.powermock:powermock-api-mockito:1.6.5'
    testImplementation 'org.powermock:powermock-module-junit4-rule-agent:1.6.5'
    testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.5'
    testImplementation 'org.powermock:powermock-module-junit4:1.6.5'
    androidTestImplementation "com.android.support:support-annotations:${supportVersion}"
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test:rules:1.0.1'
    androidTestImplementation 'org.testng:testng:6.9.6'
    androidTestImplementation 'org.mockito:mockito-core:1.10.19'
    androidTestImplementation 'com.google.dexmaker:dexmaker:1.2'
    androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
    androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3'
    androidTestImplementation("com.android.support.test.espresso:espresso-core:${espressoVersion}", {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
}

apply plugin: 'com.google.gms.google-services'

请展示你的 build.gradle 文件。 - Doug Stevenson
@DougStevenson,修改了问题 - Lahiru Chandima
你在清单中为不同的组件定义了不同的进程吗?com.my.app.core.ApplicationEx 中有什么? - Doug Stevenson
@DougStevenson,该应用程序有三种版本。ApplicationExandroid.app.Application的一个子类,在清单文件中指定为应用程序类。 - Lahiru Chandima
我了解到这些,但我想问一下你在清单文件中如何定义一些应用程序组件。除了主进程之外,您是否使用任何其他进程?ApplicationEx的内容是什么?由于您的应用程序在ApplicationEx中崩溃,因此我认为最好在那里查看一下。 - Doug Stevenson
ApplicationEx.onCreate() 中,我尝试获取消息令牌 (FirebaseInstanceId.getInstance().getToken()) 并将其发送到后端,以便后端可以将令牌注册到消息主题。我自己不启动任何其他进程,但我使用的崩溃报告库 ACRA 使用另一个进程。 - Lahiru Chandima
2个回答

1
Firebase SDK通常不支持除主进程以外的其他进程。如果ACRA启动并启动另一个进程,则其自己的进程将为该进程创建一个新的Application子类。这是因为每个应用程序进程必须实例化恰好一个Application对象。
对于您的应用程序,这意味着这个其他进程永远不应该使用Firebase API。这意味着您需要找到另一个地方获取那个IID令牌。
(请注意,Firebase SDK会自动由ContentProvider初始化,该ContentProvider默认合并到您的应用程序中-除非您已删除此ContentProvider或您未使用google-services插件,否则您永远不应该调用FirebaseApp.initializeApp()。)
通常,当应用程序需要获取IID令牌时,它们会创建FirebaseInstanceIdService的子类,如文档所述。该服务在每次知道新令牌时都会收到通知。那就是您应该检索并将其发送到服务器的地方。

感谢您的回答。您能否请澄清以下问题:1)我不应该首先调用FirebaseInstanceId.getInstance().getToken(),以便FirebaseInstanceIdService被通知有关令牌刷新的情况吗?如果是这样,在哪里应该放置它而不是ApplicationEx?2)应用程序不总是崩溃的原因是什么?3)根据您的答案,调用FirebaseApp.initializeApp()是不必要的? - Lahiru Chandima
  1. 不行。正如我所说,文档说明了您应该如何在哪里获取令牌。
  2. 应用程序并不总是崩溃,因为我怀疑ACRA并不总是启动。
  3. 除非您有我提到的罕见情况,否则没有必要。
- Doug Stevenson

0

步骤1:

从Firebase项目下载google-services.json文件,其中包含您的Firebase项目密钥和值。

"project_info": {
    "project_number": "XXXXXXXXXXXX",
    "firebase_url": "https://xxxxxxx-XXXXXX.firebaseio.com",
    "project_id": "xxxxxx-XXXXX",
    "storage_bucket": "xxxxxx-XXXXX.appspot.com"
 }

第二步: 在您的应用程序类中,您可以输入Firebase。
private FirebaseDatabase database;

public void onCreate() {
        super.onCreate();
        FirebaseApp.initializeApp(this);
        database = FirebaseDatabase.getInstance();
}

// by calling this method wherever you can use firebase database object for further operations.

public FirebaseDatabase getDataBase(){
        return database;
    }

第三步: 在您的项目级别的build.gradle文件中。
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    }) 
compile 'com.google.firebase:firebase-messaging:11.4.0'
    compile 'com.google.firebase:firebase-database:11.4.0' 
}

apply plugin: 'com.google.gms.google-services'

步骤4:
在您的项目级别的build.gradle文件中

dependencies {
    classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'com.google.gms:google-services:3.1.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

allprojects {
    repositories {
        jcenter()
        maven { url "https://maven.google.com" }// Google's Maven repository
    }
}

如需进一步了解,请阅读文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接