React-native-firebase: Manually initialise RNFirebase Messaging during runtime (many-to-many)

Created on 10 Dec 2019  路  8Comments  路  Source: invertase/react-native-firebase

Hi there,

First let us say that we love RNFirebase, great project.

Our mobile application is based on a many-to-many model, where each of our customers run their own Google Firebase account). Basically during runtime a JSON file is fetched from a central back-end server which contains the correct Firebase (messaging) settings for this particular customer.

We currently use RNFirebase V5 in combination with React Native 0.59. Now we are trying to convert our existing project to React Native 0.61 in combination with RNFirebase V6. Currently we made some hacks to make sure RNFirebase doesn't initialise Firebase during the application startup, so that we can initialise it manually from MainApplication.java. But it seems that this construction isn't compatible anymore with RNFirebase V6.

So we need to initialise RNFirebase during runtime with the proper settings. And if possible, from the Javascript side. Something like this:

firebase.messaging().setAutoInitEnabled(false);

const config = {
  clientId: 'x',
  appId: 'x',
  apiKey: 'x',
  databaseURL: 'x',
  storageBucket: 'x',
  messagingSenderId: 'x',
  projectId: 'x',
  persistence: true,
};

const defaultApp = firebase.initializeApp(config, "[DEFAULT]");

But because RNFirebase still initialises the default firebaseApp during startup our manual initialisation fails. Is there a way to accomplish this without any dirty hacks?

Kind regards,

Bastiaan

Stale

Most helpful comment

@Salakar The proposal from @defcon8 is also very important to setup multiple enviroments. It would be great to have this feature in the lib.

EDIT: Actually not very useful as some native modules (e.g. Analytics) won't work with dynamic initialization. :disappointed:

All 8 comments

Hey, v6 of RNFirebase "should" support this, you need to make sure you don't call initialise natively on iOS in your app delegate like this https://github.com/invertase/react-native-firebase/blob/master/tests/ios/testing/AppDelegate.m#L28-L30

and for Android; don't use the google services json/file plugin and it won't auto initialise the default app.

Then it's as above but a small tweak:

const config = {
  clientId: 'x',
  appId: 'x',
  apiKey: 'x',
  databaseURL: 'x',
  storageBucket: 'x',
  messagingSenderId: 'x',
  projectId: 'x',
};

// slight change from the websdk, initializeApp returns a promise as native method
// calls are async
const defaultApp = await firebase.initializeApp(config);

Worth noting though, only some modules on the official Firebase native SDK's support multiple apps instances, they are as follows:

  • Authentication
  • Database
  • Firestore
  • Functions
  • Instance ID
  • Storage
  • ML Kit Natural Language
  • ML Kit Vision

Hi Salakar,

Thanks for you extended answer! But the problem is that we need Messaging for our application. We want to initialise the default Firebase App during runtime. So basically we would like to have no multiple apps instances in our situation, just the single "default" one.

Kind regards,

Bastiaan

We solved the issue by modifying the file node_modules/@react-native-firebase/app/lib/internal/registry/app.js

We removed all functionality from the method initializeNativeApps() so that it looks like this:

export function initializeNativeApps() {
}

Then we modified the the method initializeApp to become:

export function initializeApp(options = {}, configOrName) {
  const nativeModule = getAppModule();
  const {
    NATIVE_FIREBASE_APPS
  } = nativeModule;

  if (NATIVE_FIREBASE_APPS && NATIVE_FIREBASE_APPS.length) {
    for (let i = 0; i < NATIVE_FIREBASE_APPS.length; i++) {
      const {
        appConfig
      } = NATIVE_FIREBASE_APPS[i];
      APP_REGISTRY[configOrName] = new FirebaseApp(
        options,
        appConfig,
        true,
        deleteApp.bind(null, configOrName, true),
      );
      onAppCreateFn(APP_REGISTRY[configOrName]);
    }
  }

  initializedNativeApps = true;
}

These modifications allows us to initialise Firebase default App during runtime from the Javascript side like this:

const config = {
  clientId: 'x',
  appId: 'x',
  apiKey: 'x',
  databaseURL: 'x',
  storageBucket: 'x',
  messagingSenderId: 'x',
  projectId: 'x',
  persistence: true,
};

const firebaseApp = firebase.initializeApp(config, '[DEFAULT]');

We found out that the file google-services.json is still required because else the app won't build, however the values in that file aren't used anymore. Keep in mind that during the build process the values in this file are being checked for the right format, so we entered some fake data with the proper formatting.

We know this is not a fancy solution and we still hope that there is cleaner way to accomplish this. In the meanwhile we are considering making a branch for these modifications to your library or write a patch bash script that runs before building. @Salakar What do you think? Would this be a feature that you can merge back into the trunk?

Kind regards,

Bastiaan

Just with regard to mechanisms on how to apply: I swear by the patch-package module, it is superb: https://github.com/ds300/patch-package

We found out that the file google-services.json is still required because else the app won't build, however the values in that file aren't used anymore.

You need to remove the google services plugin, otherwise this happens

@Salakar The proposal from @defcon8 is also very important to setup multiple enviroments. It would be great to have this feature in the lib.

EDIT: Actually not very useful as some native modules (e.g. Analytics) won't work with dynamic initialization. :disappointed:

Hello 馃憢, to help manage issues we automatically close stale issues.
This issue has been automatically marked as stale because it has not had activity for quite some time. Has this issue been fixed, or does it still require the community's attention?

This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.

Closing this issue after a prolonged period of inactivity. If this is still present in the latest release, please feel free to create a new issue with up-to-date information.

Was this page helpful?
0 / 5 - 0 ratings