Firebase-js-sdk: Firebase: No Firebase App '[DEFAULT]' has been created (Firestore)

Created on 23 Oct 2017  路  8Comments  路  Source: firebase/firebase-js-sdk

Environment

  • Operating System version: macOS 10.12.5
  • Firebase SDK version: 4.6.0
  • Firebase Product: firestore (auth, database, storage, etc)
  • React Native: 0.47.1
  • React: 16.0.0-alpha.12

Describe the problem:

React Native Project
Firebase had been setup in the App entrypoint for a long time using:

import firebase from 'firebase';

firebase.initializeApp({
  apiKey: '...',
  authDomain: '...',
  databaseURL: '...',
  projectId: '...',
  storageBucket: '...',
  messagingSenderId: '...',
});

and had been working properly for Firebase Database

but upon upgrading to 4.6.0 and adding trying to use within my components, I get the following error:

Unhandled JS Exception: Firebase: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp() (app/no-app).

Relevant Code:

import firebase from 'firebase';
import 'firebase/firestore';

const db = firebase.firestore();
firestore

Most helpful comment

Just to chime in here, when you are attempting to use firebase without passing a Firebase app around, load order matters.

An example:

You have two files: foo.js and bar.js

foo.js

import firebase from 'firebase/app';
firebase.initializeApp({ ... });

bar.js

import firebase from 'firebase/app';
import 'firebase/firestore';

const db = firebase.firestore();

In this scenario, loading bar.js before foo.js will fail 100% of the time. In reality bar.js has a dependency on the app created in foo.js and you should either:

import foo.js before bar.js in all cases where you need bar.js

OR (and much easier to reason about)

Add a dependency to foo.js in bar.js as you need the app created there.

An easier way to do this would be to actually pass around the FirebaseApp created by calling initializeApp(). That would look something like this:

foo.js

import firebase from 'firebase/app';
export const app = firebase.initializeApp({ ... });

bar.js

import { app } from 'foo.js';
import firebase from 'firebase/app';
import 'firebase/firestore';

const db = firebase.firestore(app);

Now you are much more explicit about your dependencies and the code will always load in the correct order.

All 8 comments

Hmmm this issue does not seem to follow the issue template. Make sure you provide all the required information.

Seems like this will turn out to be a timing issue, and that firebase.firestore() is likely getting invoked before your firebase.initializeApp() code. But there's not enough code here to tell, since the relationship of those two code snips is unclear.

Thanks @katowulf . It seems it's actually a timing issue like you suggested. I was calling:
const db = firebase.firestore() in a Component's constructor so I didn't expect it to get fired on App load, since that Component is not rendered yet. But I noticed I don't get the error if I make the call in a function elsewhere.

If anyone else stumbles upon this, you can do a simple interval check to await the initial app construction.

let firebaseAppDefined = false

setInterval(() => {
  if (!firebaseAppDefined) {
    if (firebase.app()) {
      // Your code here

      firebaseAppDefined = true
    }
  }
}, 100)

In my case I had to wait until the app was ready before being able to initialize FirebaseUI (auth widget).

@corysimmons thanks for the workaround, Cory. I wish there is an event which alarms when a firebase app initialized so we don't have to set intervals.

Same. I wish more companies ate their own dog food in combination with whatever the most likely tech their product will be used with (React) then provided tons of resources and special treatment for those things.

Just to chime in here, when you are attempting to use firebase without passing a Firebase app around, load order matters.

An example:

You have two files: foo.js and bar.js

foo.js

import firebase from 'firebase/app';
firebase.initializeApp({ ... });

bar.js

import firebase from 'firebase/app';
import 'firebase/firestore';

const db = firebase.firestore();

In this scenario, loading bar.js before foo.js will fail 100% of the time. In reality bar.js has a dependency on the app created in foo.js and you should either:

import foo.js before bar.js in all cases where you need bar.js

OR (and much easier to reason about)

Add a dependency to foo.js in bar.js as you need the app created there.

An easier way to do this would be to actually pass around the FirebaseApp created by calling initializeApp(). That would look something like this:

foo.js

import firebase from 'firebase/app';
export const app = firebase.initializeApp({ ... });

bar.js

import { app } from 'foo.js';
import firebase from 'firebase/app';
import 'firebase/firestore';

const db = firebase.firestore(app);

Now you are much more explicit about your dependencies and the code will always load in the correct order.

@corysimmons actually there is a callback dude:

const config = {};
firebase.initializeApp(config);
firebase.auth().onAuthStateChanged(function(user) {
            if (user) {
                // User is signed in and currentUser will no longer return null.
            } else {
                // No user is signed in.
            }
        });
Was this page helpful?
0 / 5 - 0 ratings