我可以不使用google-services.json文件初始化Firebase吗?

25

编辑:我应该强调,我有某些口味,不想使用这些谷歌服务,并且试图在这种情况下应用google-services插件,而没有可适用的google-services.json,会导致构建失败。

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

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

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

FirebaseInitProvider: FirebaseApp initialization unsuccessful

我知道使用google-services.json文件是推荐的方式,但我需要能够使应用程序调用不同的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);

到目前为止,似乎它还没有起作用。

非常感谢所有的帮助!


1
虽然不是回答你的问题,但或许有所帮助:Google Services Gradle Plugin 的文档解释了你可以为一个项目使用多个 google-services.json 文件来支持不同的构建类型和风格。 - Bob Snyder
@qbix,谢谢,我已经更新了我的问题。我知道这个,但问题是我有一些口味,我不想使用任何这些Google服务,因为我不需要它们。如果我仍然不提供google-services.json,构建将失败。 - Matej
这对我有用:https://dev59.com/YVoU5IYBdhLWcg3wQ1d3#37643374。你遇到了什么问题? - Frank van Puffelen
@FrankvanPuffelen 可能需要给FirebaseApp实例命名非默认名称,才能成功手动初始化。但问题在于,FirebaseRemoteConfig没有参数化的getInstance方法,无法传递这样的非默认FirebaseApp实例。因此,在调用FirebaseRemoteConfig.getInstance时,应用程序会崩溃。 - Matej
所以我正在尝试做完全相同的事情,但是出现了一个错误:缺少google_app_id。 Firebase Analytics已禁用。 - 看起来它需要一个资源值。如果我提供无效值,它会崩溃,如果我提供有效值,它将使用该值,而不管我在setApplicationId()中写什么 - 有什么帮助吗? - user230910
显示剩余3条评论
4个回答

19
以下是如何在同一个Android项目中使用多个Firebase应用/数据库的一些指南:Firebase Blog新配置文档

然而,这些文章都是关于在默认应用程序之外使用辅助应用程序的,仍然需要使用google-services.json。我进行了一些研究并在他们的Slack频道中探索了一下。Firebase使用名为FirebaseInitProvider的ContentProvider来初始化启动时的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即可。只需要确保在Application::onCreate方法的第一件事中调用Firebase.initializeApp。

FirebaseApp.initializeApp(context, new FirebaseOptions.Builder().setApiKey("<VAL>").
                    setApplicationId("<VAL>").
                    setDatabaseUrl("<VAL>").
                    setGcmSenderId("<VAL>").
                    setStorageBucket("<VAL>").build());  

我已经尝试过了,但对我没有用。这是哪个版本的Firebase? - user1743524
1
@user1743524 我已经尝试过使用10.0.1版本,对我来说似乎可以工作。 - exifguy
1
@exifguy 当应用程序被杀死并收到推送通知(使用与上述相同的方法)时,我会收到“Default FirebaseApp未初始化”的错误。 对于您是否有效呢? - dabo248

5
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_idgoogle_app_id,而Firebase Auth还需要google_api_key。进行实验并找出您需要哪些密钥应该不太难。

一些链接:


2
我找到了一个有趣的解决方法。请尝试以下步骤: 将你的 google-services.json 文件放入任何一个提供 Firebase 集成的示例应用中。编译它。 查看路径 app/build/generated/res/google-services/debug/values/,那里应该会生成一个包含在你描述的错误中提到的一堆字符串的 values.xml 文件。将这些字符串复制到你项目的 value.xml 文件中,就完成了。

1
对我也起作用了。但不要忘记从清单中删除FirebaseInitProvider - Dokumans

1
我还使用构建变体来应用不同环境的不同配置。 我遇到了相同的问题,因为一些变体在google-services.json文件中没有适当的条目。这导致我的某些构建在生成未在firebase中配置的应用程序包时失败。
我的解决方法是在相关的firebase项目上为缺少的包添加虚拟应用程序条目,然后从firebase仪表板获取更新的google-services.json文件。
可能不是最佳实践,但在我的情况下完成了工作。

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