19

编辑:我应该强调,我有一些口味,我不想使用这些 Google 服务中的任何一个,并且在没有适用的 google-services.json 的情况下尝试在这种情况下应用 google-services 插件,会导致构建失败。

我希望能够初始化 Firebase SDK,特别是使用远程配置,而不使用 google-services.json。

我看到 FirebaseApp 有一个初始化方法,它接收一个 FirebaseOptions 对象。

我已经使用 google-services.json 中提供的值构建了 FirebaseOptions,并且在使用这些选项调用 FirebaseApp.initialize 后,我总是得到

FirebaseInitProvider: FirebaseApp initialization unsuccessful

我知道这是使用 google-services.json 文件的推荐方式,但我需要能够使应用程序调用不同的 Firebase 项目,具体取决于调试/发布版本,同时保持包名称相同。

我想这样做的方法是为初始化 Firebase 所需的所有值设置一个调试/发布对,然后动态地进行初始化。

        FirebaseOptions options = new FirebaseOptions.Builder()
                .setApplicationId(appId)
                .setApiKey(apiKey)
                .setGcmSenderId(appContext.getString(
                        isDebug ? R.string.firebase_testing_gcm_sender_id :
                                R.string.firebase_production_gcm_sender_id))
                .setDatabaseUrl(appContext.getString(
                        isDebug ? R.string.firebase_testing_database_url :
                                R.string.firebase_production_database_url))
                .setStorageBucket(
                        appContext.getString(
                                isDebug ? R.string.firebase_testing_storage_bucket :
                                        R.string.firebase_production_storage_bucket))
                .build();
        FirebaseApp.initializeApp(appContext, options);

到目前为止,它似乎不起作用。

非常感谢所有帮助!

4

4 回答 4

18

以下是关于如何在同一个 android 项目Firebase 博客新配置文档中使用多个 firebase 应用程序/数据库的一些提示

然而,这些谈论使用除了默认应用程序之外的辅助应用程序——它仍然使用 google-services.json。我做了一些研究并在他们的 Slack 频道中闲逛。Firebase 使用名为 FirebaseInitProvider 的 ContentProvider。这使用 google-services.json 在启动时初始化 DEFAULT 应用程序。如果 json 文件不存在,它会报错。我做了以下步骤:

  • 删除了 google-services.json
  • 删除了 com.google.gms.google-services 插件。这个插件总是寻找 json 文件。
  • FirebaseInitProvider 通过清单合并添加。但是,在顶级清单中,您可以指定 node=remove 标记以将其从添加到最终清单中删除。

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

但是,即使在此之后,我仍然看到一个异常:

java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process myfirebasedemo.net. 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.google.firebase.iid.FirebaseInstanceIdService.zza(Unknown Source)
                                                                 at com.google.firebase.iid.FirebaseInstanceIdService.zzm(Unknown Source)
                                                                 at com.google.firebase.iid.zzb$2.run(Unknown Source)
                                                                 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)

看起来 FirebaseInstanceIdService 仍在寻找实例应用程序。如果您使用相同的清单节点删除技术禁用该服务,那么此异常就会消失。但我认为这个服务做重要的同步/消息传递的东西。所以不确定删除它是否明智。长话短说——我仍在寻找禁用默认应用程序/不使用 google-services.json 的完美解决方案。任何进一步的指示将不胜感激。

更新:

看起来这个解决方案毕竟有效 - 没有禁用 FirebaseInstanceIdService 并且只是删除了上面提到的 FirebaseInitProvider 。只需要确保 Firebase.initializeApp 在 Application::onCreate 方法中调用了第一件事。

FirebaseApp.initializeApp(context, new FirebaseOptions.Builder().setApiKey("<VAL>").
                    setApplicationId("<VAL>").
                    setDatabaseUrl("<VAL>").
                    setGcmSenderId("<VAL>").
                    setStorageBucket("<VAL>").build());  
于 2016-12-23T17:05:34.470 回答
3

google-services.json是完全可选的并且意味着方便。因此,如果您觉得不方便,请绝对不要使用它。

您可能已经注意到,该json文件仅在构建时使用。该google-services插件将 JSON 文件转换为xml包含一些特定字符串的资源文件。它看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <! -- Present in all applications -->
    <string name="google_app_id" translatable="false">1:1035469437089:android:73a4fb8297b2cd4f</string>

    <! -- Present in applications with the appropriate services configured -->
    <string name="gcm_defaultSenderId" translatable="false">1035469437089</string>
    <string name="default_web_client_id" translatable="false">337894902146-e4uksm38sne0bqrj6uvkbo4oiu4hvigl.apps.googleusercontent.com</string>
    <string name="ga_trackingId" translatable="false">UA-65557217-3</string>
    <string name="firebase_database_url" translatable="false">https://example-url.firebaseio.com</string>
    <string name="google_api_key" translatable="false">AIzbSyCILMsOuUKwN3qhtxrPq7FFemDJUAXTyZ8</string>
    <string name="google_crash_reporting_api_key" translatable="false">AIzbSyCILMsOuUKwN3qhtxrPq7FFemDJUAXTyZ8</string>
    <string name="project_id" translatable="false">mydemoapp</string>

</resources>

您可以在自己的strings.xml文件中创建这些条目,然后FirebaseApp.initializeApp()在运行时找到它们。并非所有密钥都是必需的,这取决于您使用的服务。例如,几乎所有服务都需要google_app_id密钥。Firestore 只需要 that 和project_id,而 Firebase Authgoogle_api_key也需要 。尝试并找出您需要哪些应该不会太难。

一些链接:

于 2019-06-14T15:41:54.843 回答
2

我找到了有趣的解决方法。尝试以下操作:将您的应用放到google-services.jsongoogle为 Firebase 集成提供的任何示例应用中。编译它。

查看路径app/build/generated/res/google-services/debug/values/ ,应该生成values.xml包含您描述的错误中提到的字符串的文件。将这些字符串复制到项目的 value.xml 文件中。就是这样。

于 2017-06-06T18:03:16.130 回答
1

我还使用构建变体为不同的环境应用不同的配置。我遇到了同样的问题,因为某些变体在文件中没有适当的条目google-services.json。这导致我的一些构建在生成未在 firebase 中配置的应用程序包时失败。

我的解决方法是在 firebase 仪表板上为相关 firebase 项目中缺少的包添加虚拟应用程序条目 - 然后google-services.json从中获取更新的文件。

可能不是最佳实践,但在我的情况下完成了这项工作。

于 2016-12-25T15:30:22.040 回答