【问题标题】:FirebaseApp name [DEFAULT] already existsFirebaseApp 名称 [DEFAULT] 已存在
【发布时间】:2016-08-27 22:38:34
【问题描述】:

我正在尝试在 Application 上手动初始化 FirebaseApp,但收到此错误。

public class BaseApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        FirebaseOptions firebaseOptions = new FirebaseOptions.Builder()
              .setDatabaseUrl("[DATABASE_URL]")
              .setApiKey("API_KEY")
              .setApplicationId("PROJECT_ID").build();
        FirebaseApp.initializeApp(getApplicationContext(),firebaseOptions);

        if (!FirebaseApp.getApps(this).isEmpty()) {
            FirebaseDatabase.getInstance().setPersistenceEnabled(true);
        }
    }

假设我相应地设置了firebaseOptions 值。 我希望这将为FirebaseApp 设置值。

我错过了什么吗? FirebaseApp Documentation

默认应用实例在应用启动时由 FirebaseInitProvider。这是 Gradle 将其添加到应用程序清单中的 清单合并。如果应用程序使用不同的构建系统 provider 需要手动添加到应用的清单中。

或者 initializeApp(Context, FirebaseOptions) 初始化 默认应用实例。此方法应从 Application 调用。 如果它在应用程序的主程序之外使用,这也是必要的 过程。

   FATAL EXCEPTION: main
    Process: com.sample.android, PID: 5490
    java.lang.RuntimeException: Unable to create application com.android.tools.fd.runtime.BootstrapApplication: java.lang.IllegalStateException: FirebaseApp name [DEFAULT] already exists!
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4331)
    at android.app.ActivityThread.access$1500(ActivityThread.java:135)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5001)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:801)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:617)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.IllegalStateException: FirebaseApp name [DEFAULT] already exists!
    at com.google.android.gms.common.internal.zzab.zza(Unknown Source)
    at com.google.firebase.FirebaseApp.initializeApp(Unknown Source)
    at com.sample.android.activities.BcodeApplication.onCreate(BcodeApplication.java:21)
    at com.android.tools.fd.runtime.BootstrapApplication.onCreate(BootstrapApplication.java:369)
    at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4328)
    at android.app.ActivityThread.access$1500(ActivityThread.java:135) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:136) 
    at android.app.ActivityThread.main(ActivityThread.java:5001) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:515) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:801) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:617) 
    at dalvik.system.NativeStart.main(Native Method) 

【问题讨论】:

  • 能分享一下stacktrace吗?
  • 添加了堆栈跟踪
  • 这可能是在尝试初始化同一个 FirebaseApp 两次,一次在主进程中,一次在崩溃报告进程 background_crash 中。在这里查看我的解决方案stackoverflow.com/a/40589423/1717213

标签: android firebase


【解决方案1】:

使用这个

FirebaseOptions options = new FirebaseOptions.Builder()
    .setApiKey(apiKey)
    .setApplicationId(appId)
    .setDatabaseUrl(firebaseBaseUrl)
    .build();

boolean hasBeenInitialized=false;
List<FirebaseApp> firebaseApps = FirebaseApp.getApps(mContext);
for(FirebaseApp app : firebaseApps){
    if(app.getName().equals(FirebaseApp.DEFAULT_APP_NAME)){
        hasBeenInitialized=true;
        finestayApp = app;
    }
}

if(!hasBeenInitialized) {
    finestayApp = FirebaseApp.initializeApp(mContext, options);
}

【讨论】:

  • 每当尝试通过覆盖选项访问性能实例时,您可能想尝试FirebaseApp.getInstance("FIREBASE_INSTANCE_NAME")[FirebasePerformance::class.java].isPerformanceCollectionEnabled = true
【解决方案2】:

不清楚你的目标是什么。如果您只是想修改(“覆盖”)由FirebaseInitProvider 创建的默认FirebaseApp,我认为这是不可能的。您引用的文档有点误导,因为它表明它可能的。我认为该文档旨在描述如何在尚未创建默认应用程序时对其进行初始化,例如在辅助进程中。

可以使用FirebaseApp.initializeApp()创建另一个应用对象。您需要使用接受应用名称参数的方法:

    FirebaseOptions firebaseOptions = new FirebaseOptions.Builder()
          .setDatabaseUrl("[DATABASE_URL]")
          .setApiKey("API_KEY")
          .setApplicationId("PROJECT_ID").build();

    FirebaseApp myApp = FirebaseApp.initializeApp(getApplicationContext(),firebaseOptions,
        "MyAppName");

然后您可以使用创建的FirebaseApp 来获取FirebaseDatabaseFirebaseStorageFirebaseAuthFirebaseCrashFirebaseInstanceId 的实例。例如:

FirebaseDatabase database = FirebaseDatabase.getInstance(myApp);

在应用程序的主进程中,我认为没有一种简单的方法可以禁用FirebaseInitProvider 所做的初始化处理。如果您想覆盖通常来自google-services.json 的配置参数,您可以使用documentation 中的信息为Google 服务插件创建自己的XML 文件。它指出:

如果您的 Android 项目有一些配置阻止您 使用 google-services 插件,您可以安全地重新创建 XML 使用这些值手动创建文件

我不知道这有多简单或可维护性。

【讨论】:

  • > 我认为没有简单的方法可以禁用 FirebaseInitProvider 完成的初始化处理。
【解决方案3】:

其实可以根据这篇博文here替换默认的FirebaseApp。

步骤如下: 1. 在 Android Manifest 中禁用 FirebaseInitProvider

<provider
    android:name="com.google.firebase.provider.FirebaseInitProvider"
    android:authorities="${applicationId}.firebaseinitprovider"
    tools:node="remove"
    />

2。创建自己的 ContentProvider,在 AndroidManifest 中注册。作为示例,您可以使用 FirebaseInitProvider。在内部,使用 FirebaseOptions 构建器创建 Firebase 默认应用。

FirebaseOptions.Builder builder = new FirebaseOptions.Builder()
    .setApplicationId("1:0123456789012:android:0123456789abcdef")
    .setApiKey("your_api_key")
    .setDatabaseUrl("https://your-app.firebaseio.com")
    .setStorageBucket("your-app.appspot.com");
FirebaseApp.initializeApp(this, builder.build());

【讨论】:

    【解决方案4】:

    您可以检查它是否处于活动状态:

    !firebase.apps.length ? firebase.initializeApp(config) : firebase.app();
    

    【讨论】:

      【解决方案5】:

      在 onCreate() 中:

          ...                                                                    
            if (!checkInternet()) {
              showMessageDialog("Enable Internet connection please.", true);
              finish();
      
          } else {
      
              boolean hasBeenInitialized = false;
              List<FirebaseApp> fbsLcl = FirebaseApp.getApps(this);
              for (FirebaseApp app : fbsLcl) {
                  if (app.getName().equals("SpeachGAPIMyTest")) {
                      hasBeenInitialized = true;
                  }
              }
      
              FirebaseOptions options = new FirebaseOptions.Builder()
                      .setApiKey("AIzaSyA6172grz_K_jkhfvXsrUUiug9LwImK3sg26bE")//https://console.developers.google.com/apis/credentials?project=speachgapimytest-72e23
                      .setApplicationId("uz.my.speach.gapi")
                      .setDatabaseUrl("https://speachgapimytest-72e23.firebaseio.com/")
                      .build();
              if (!hasBeenInitialized) 
                  fbApp = FirebaseApp.initializeApp(getApplicationContext(), options, "SpeachGAPIMaximTest"/*""*/);
              else
                  fbApp = FirebaseApp.getInstance("SpeachGAPIMyTest");
              fbDB = FirebaseDatabase.getInstance(fbApp); 
      
              startAuthDialog();                                                
              ...
      
      
          }
      

      【讨论】:

        【解决方案6】:

        我建议您在整个项目中搜索“FirebaseApp.InitializeApp”,如果您正在学习教程或正在修改开源项目,您可能已经在其他地方初始化它并忘记了它例如来自 GitHub。

        有时错误信息是如此简单以至于我们忽略它,因为错误说“已经存在”然后给它一个机会并搜索它。

        【讨论】:

          【解决方案7】:

          我相信我理解你想要做什么,(你在做多线程编程对吗?我从 if empty 猜到了)。我假设您希望在每次运行特定线程时自动添加新的 FirebaseApp。 如果是这样的话。这就是我解决它的方式。 我每次都添加了一个随机生成器来命名。

          这是我的代码:

          SecureRandom random = new SecureRandom();
          options = new FirebaseOptions.Builder()
                          .setCredentials(credentials)
                          .build();
                  String name = String.valueOf(random.nextInt());
                  FirebaseApp.initializeApp(options,name);
              db = FirestoreClient.getFirestore(FirebaseApp.getInstance(name));
          

          【讨论】:

            【解决方案8】:

            只需用 try and catch 包装它。

            try{
            FirebaseApp.initializeApp(getApplicationContext(),firebaseOptions);
            }catch(_){}

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-09-17
              • 2019-12-04
              • 2016-12-07
              • 2021-10-17
              • 2017-04-25
              • 1970-01-01
              • 2019-07-09
              相关资源
              最近更新 更多