I'm trying to add authentication to my Angular/Firebase app. I got it working no-problem in a small demo app, but when I try to add it to my real Angular application, I get "Component auth has not been registered yet" console errors in the browser.
To narrow the issue down, I copied this minimal authentication component from the Firebase "angularfire" samples ():
import { Component, OnInit, OnDestroy, PLATFORM_ID } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import firebase from '@firebase/app-compat';
import { Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
import { trace } from '@angular/fire/compat/performance';
import { Inject } from '@angular/core';
import { isPlatformServer } from '@angular/common';
@Component({
selector: 'app-auth',
template: `
<p>
Auth!
{{ (auth.user | async)?.uid | json }}
{{ (auth.credential | async)?.additionalUserInfo?.isNewUser | json }}
<button (click)="login()" *ngIf="showLoginButton">Log in with Google</button>
<button (click)="loginAnonymously()" *ngIf="showLoginButton">Log in anonymously</button>
<button (click)="logout()" *ngIf="showLogoutButton">Log out</button>
</p>
`,
styles: []
})
export class AuthComponent implements OnInit, OnDestroy {
private readonly userDisposable: Subscription | undefined;
showLoginButton = false;
showLogoutButton = false;
constructor(public readonly auth: AngularFireAuth, @Inject(PLATFORM_ID) platformId: object) {
if (!isPlatformServer(platformId)) {
this.userDisposable = this.auth.authState.pipe(
trace('auth'),
map(u => !!u)
).subscribe(isLoggedIn => {
this.showLoginButton = !isLoggedIn;
this.showLogoutButton = isLoggedIn;
});
}
}
ngOnInit(): void { }
ngOnDestroy(): void {
if (this.userDisposable) {
this.userDisposable.unsubscribe();
}
}
async login() {
const user = await this.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
// TODO sign into offline app
}
async loginAnonymously() {
const user = await this.auth.signInAnonymously();
// TODO sign into offline app
}
logout() {
this.auth.signOut();
// TODO sign out of offline app
}
}
The imports section of my app.module.ts looks like this (edited):
imports: [
AppRoutingModule,
...
AngularFireModule.initializeApp(environment.firebase),
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAnalytics(() => getAnalytics()),
provideAuth(() => getAuth()),
provideFirestore(() => getFirestore()),
provideFunctions(() => getFunctions()),
],
The console error that I'm seeing looks like this:
zone.js:182 Uncaught Error: Component auth has not been registered yet at Provider.initialize (index.esm2017.js:232:19) at new Auth (index.esm2017.js:651:35) at Component.instance.INTERNAL.registerComponent.firebase_component__WEBPACK_IMPORTED_MODULE_3_.Component.setServiceProps.ActionCodeInfo.Operation.EMAIL_SIGNIN [as instanceFactory] (index.esm2017.js:969:16) at Provider.getOrInitializeService (index.esm2017.js:290:39) at Provider.getImmediate (index.esm2017.js:128:29) at FirebaseAppImpl._getService (index.esm2017.js:83:1) at FirebaseAppImpl.firebaseAppImpl. [as auth] (index.esm2017.js:291:1) at angular-fire-compat-auth.js:59:51 at ZoneDelegate.invoke (zone.js:372:1) at Zone.run (zone.js:134:1)
I've examined the Authentication settings of my app in the Firebase console, and they're identical for what I have set in my demo app, which works.
Any suggestions?
Wew, that took hours and hours or work to narrow down the issue!
I finally figured out that the problem was that I had "@firebase/app" in my dependencies and that was causing the error. I'm guessing that it conflicted with the "@angular/fire" package, or something similar. I removed it, and Firebase authentication is now working in my app.