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

Matej picture Matej · Aug 15, 2016 · Viewed 11.8k times · Source

EDIT: I should emphasize, I have flavors, for which I don't want to use any of these Google services, and attempting to apply the google-services plugin in such a case, without having an applicable google-services.json, would result in a failed build.

I would like to be able to initialize the Firebase SDK, specifically to use the Remote Config, WITHOUT using the google-services.json.

I see that FirebaseApp has an initialize method, which receives a FirebaseOptions object.

I've built the FirebaseOptions with values provided in the google-services.json, and after a call to FirebaseApp.initialize with these options, I always get

FirebaseInitProvider: FirebaseApp initialization unsuccessful

I know it's the recommended way to use the google-services.json file, but I need to be able to make the app call different Firebase projects, depending on debug/release builds, while keeping the package name the same.

The way I would like to do this is to have a debug/release pairs for all values necessary to initialize Firebase, and then dynamically do the initialization.

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

So far it doesn't seem to work.

All help is greatly appreciated!

Answer

exifguy picture exifguy · Dec 23, 2016

Here are couple pointers on how to use multiple firebase apps / databases in the same android project Firebase Blog and New Config Docs

However these talk about using a secondary app in addition to the default app -- which still uses the google-services.json. I did a little bit of research and poking around in their Slack channel. Firebase uses a ContentProvider called FirebaseInitProvider. This uses the google-services.json to initialize the DEFAULT app at start up. It barfs if the json file is not present. I did the following steps:

  • Removed the google-services.json
  • Removed com.google.gms.google-services plugin. This plugin always looks for the json file.
  • FirebaseInitProvider is added via manifest merging. However in the top level manifest you can specify a node=remove tag to remove this from being added in the final manifest.

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

However, even after this, I still see an exception:

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)

Looks like FirebaseInstanceIdService still looks for the instance app. If you disable the service, using the same manifest node removal technique then this exception goes away. But I think this Service does important sync-ing / messaging stuff. So not sure if its wise to remove this. Long story short -- I am still looking for the perfect solution for disabling the default app / not using the google-services.json. Any further pointers will be deeply appreciated.

UPDATE:

Looks like this solution works after all -- without disabling the FirebaseInstanceIdService and just removing the FirebaseInitProvider as mentioned above. Just need to make sure that the Firebase.initializeApp called the first thing in Application::onCreate method.

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