NullInjectorError: No provider for InjectionToken angularfire2.app.options! 2021

Solution 1:

It seems that AngularFire is in the middle of major changes that embrace Firebase's new modular API, but the documentation hasn't quite caught up. The gist is that the you are initializing the Firebase App using the new API, but trying to use Firebase resources with the old API.

The key is to look at the import statement. Compare old and new style of initializing the app:

import {AngularFireModule} from '@angular/fire/compat';

[...]

imports: [
    AngularFireModule.initializeApp(environment.firebase),
]

vs.

import {initializeApp, provideFirebaseApp} from '@angular/fire/app';

[...]

imports: [
    provideFirebaseApp( () => initializeApp(environment.firebase)),
]

Notice how the old style initialization is under the "compat" namespace. If you initialize your app this way, you must also use the compat libraries to access resources. For example, from the AngularFire docs:

import {AngularFirestore, AngularFirestoreDocument} from '@angular/fire/compat/firestore';

[...]

constructor(private afs: AngularFirestore) {
    this.itemDoc = afs.doc<Item>('items/1');
    this.item = this.itemDoc.valueChanges();
  }

However, this doesn't work with the new style app initialization. Instead you must use something like this, adapted from the Firebase docs:

import {doc, Firestore, getDoc} from '@angular/fire/firestore';

[...]

constructor(private firestore: Firestore) { }

[...]

const docRef = doc(this.firestore, "cities", "SF");
const docSnap = await getDoc(docRef);

Why does it matter? I assume, but do not know, that the instance of the app is not shared between old and new.

So, the moral of the story:

  • Most of the documentation on the internet uses the old API. If you want to use that API, use the "compat" version of the library.
  • If you want to use the modern modular API, make sure you're not using the "compat" library. And the best bet is to refer to the Firebase documentation until the AngularFire team has had a chance to catch up.

Solution 2:

I had the same problem today and I agree: there's many versions and their documentation is disappointing.

The solution (in my case)

For my setup (angular 11 + angular/fire 6.1.5) i had to put the following in my app.module.ts file:

...
    imports: [
        ...
        AngularFireModule.initializeApp(environment.firebase),
    ],
...

(For me environment.firebase contains my firebase config.)

Further analysis of the problem below, you can stop reading if you don't care

The documentation for angular/fire 7 will tell you to do this:

provideFirebaseApp(() => initializeApp(environment.firebase)),

Which I'm sure works great for version 7, but angular 11 automatically installs version 6, because that's compatible.