我可以在不使用 google-services.json 的情况下初始化 Firebase 吗?

Can I initialize Firebase without using google-services.json?

编辑:我应该强调,我有自己的风格,我不想使用这些 Google 服务中的任何一个,并试图在这样的情况下应用 google-services 插件如果没有适用的 google-services.json,将导致构建失败。

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

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

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

FirebaseInitProvider: FirebaseApp initialization unsuccessful

我知道这是使用 google-services.json 文件的推荐方式,但我需要能够让应用调用不同的 Firebase 项目,具体取决于 debug/release 构建,同时保持包名称相同。

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

        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);

目前看来还不行。

非常感谢所有帮助!

这里有一些关于如何在同一个 android 项目中使用多个 firebase 应用程序/数据库的指南 Firebase Blog and New Config Docs

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

  • 删除了 google-services.json
  • 删除了 com.google.gms.google-services 插件。此 plugin 始终查找 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.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());  

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

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

可能不是最佳做法,但在我的案例中起到了作用。

我找到了有趣的解决方法。尝试以下操作: 将您的 google-services.json 放入任何示例应用程序 google provides 以进行 Firebase 集成。编译它。

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

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 只需要那个和 project_id,而 Firebase Auth 也需要 google_api_key。试验并找出您需要哪些应该不难。

一些链接: