36
votes

I have upgraded to the new API and don't know how to initialize Firebase references in two separate files:

    /* CASE 1 */
    // 1st file
    var config = {/* ...  */};
    firebase.initializeApp(config);
    var rootRef = firebase.database().ref();

    // 2nd file - initialize again
    var config = {/* ...  */};
    firebase.initializeApp(config);
    var rootRef = firebase.database().ref();

RESULT: bundle.js:535 Uncaught Error: Firebase App named '[DEFAULT]' already exists.

    /* CASE 2 */
    // 1st file
    var config = {/* ...  */};
    firebase.initializeApp(config);
    var rootRef = firebase.database().ref();

    // 2nd file - don't initialize
    var rootRef = firebase.database().ref();

RESULT: bundle.js:529 Uncaught Error: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp().

Before the new API I just called

var myFirebaseRef = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/");

in each file, and it worked okay.

5

5 Answers

55
votes

This is an issue I ran into as well upgrading to the new version of Firebase. You might want two separate firebase apps initialized, like explained in other answers, but I just wanted to use the refs in two different locations in my app and I was getting the same error.

What you need to do for this situation is to create a firebase module for your app that only initializes firebase once, then you import or require it elsewhere in your app.

This is pretty simple, here is mine: modules/firebase.js

import firebase from 'firebase';
var firebaseConfig = {
  apiKey: "some-api-key",
  authDomain: "some-app.firebaseapp.com",
  databaseURL: "https://some-app.firebaseio.com",
  storageBucket: "some-app.appspot.com",
};

var FbApp = firebase.initializeApp(firebaseConfig);
module.exports.FBApp = FbApp.database(); //this doesnt have to be database only

And then elsewhere in your application you simply:

import FBApp from '/your/module/location'
var messagesRef = FBApp.ref("messages/");
32
votes

You need to name your different instances (Apps as Firebase calls them); by default you're working with the [DEFAULT] App, because that's the most common use case, but when you need to work with multiple Apps then you have to add a name when initialising:

// Intialize the "[DEFAULT]" App
var mainApp = firebase.intializeApp({ ... });

// Intialize a "Secondary" App
var secondaryApp = firebase.initializeApp({ ... }, "Secondary");
...
mainApp.database().ref("path/to/data").set(value);
secondaryApp.database().ref("path/to/data").set(anotherValue);

You can find a more example scenarios in the updated Initialize multiple apps section of the Add Firebase to your JavaScript Project guide.

6
votes

If you don't have the control over where Firebase will be instantiated, you can do something like this:

 try {
    let firApp = firebase.app(applicationName);
    return firApp;
  } catch (error) {
    return firebase.initializeApp({
      credential: firebase.credential.cert(firebaseCredentials),
      databaseURL: firebaseUrl
    }, applicationName);
  }

Firebase will try to get the application, if it doesn't exist, then you can initialize it freely.

3
votes

I made the mistake by importing like this.

import firebase from 'firebase'

const firebaseConfig = {
  apiKey: 'key',
  authDomain: 'domain',
  databaseURL: 'url',
  storageBucket: ''
};

firebase.initializeApp(firebaseConfig);

This worked fine for a few days but when I tried to sign in with custom tokens my auth object was not changed. I had to refresh the page for it to update so I could make certain calls to the database which were protected by my own auth credentials rules.

 ".read": "$uid === auth.uid || auth.isAdmin === true || auth.isTeacher === true",

When I changed my imports to this it worked again.

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/database';

const firebaseConfig = {
  apiKey: 'key',
  authDomain: 'domain',
  databaseURL: 'url',
  storageBucket: ''
};

firebase.initializeApp(firebaseConfig);

Then whenever I need to use Firebase in a certain module I import this(notice the import from firebase/app instead of firebase):

import firebase from 'firebase/app';

And talk to certain services like so:

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    // Authenticated.
  } else {
    // Logged out.
  }
});

firebase.database().ref('myref').once('value').then((snapshot) => {
  // do stuff with the snapshot
});
2
votes

To make multiple instances using new firebase.initializeApp(), you need a second parameter for the firebase constructor:

firebase.initializeApp( {}, "second parameter" );

Compare it to the old way to generate multiple instances where

new Firebase.Context() 

is the second parameter:

new Firebase('', new Firebase.Context() );