I am using ionic 7 and angular fire for authentication using firebase. Lot of code on the internet uses older way of app.module.ts which is no longer the way. So, i created a new firebase.module as below
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { provideAuth, getAuth } from '@angular/fire/auth';
import { provideFirestore, getFirestore } from '@angular/fire/firestore';
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "XXXXX",
...
};
@NgModule({
declarations: [],
imports: [
CommonModule,
provideFirebaseApp(
() => initializeApp(firebaseConfig)),
provideAuth(() => getAuth()),
provideFirestore(() => getFirestore(),
),
],
providers: []
})
export class FirebaseModule { }
The auth service file looks like below
//reference https://www.positronx.io/ionic-firebase-authentication-tutorial-with-examples/
import { Injectable, NgZone } from '@angular/core';
import {
AngularFirestore,
AngularFirestoreDocument,
} from '@angular/fire/compat/firestore';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import { Router } from '@angular/router';
import { User } from './modal/user.modal';
import * as auth from 'firebase/auth';
@Injectable({
providedIn: 'root'
})
export class AuthenticationServiceService {
userData: any;
constructor( public afStore: AngularFirestore,
public ngFireAuth: AngularFireAuth,
public router: Router,
public ngZone: NgZone) {
this.ngFireAuth.authState.subscribe((user) => {
if (user) {
this.userData = user;
localStorage.setItem('user', JSON.stringify(this.userData));
JSON.parse(localStorage.getItem('user') || '{}');
} else {
localStorage.setItem('user', null || '{}');
JSON.parse(localStorage.getItem('user') || '{}');
}
});
}
// Returns true when user is looged in
get isLoggedIn(): boolean {
const user = JSON.parse(localStorage.getItem('user') || '{}');
return user !== null && user.emailVerified !== false ? true : false;
}
// Returns true when user's email is verified
get isEmailVerified(): boolean {
const user = JSON.parse(localStorage.getItem('user') || '{}');
return user.emailVerified !== false ? true : false;
}
// Sign in with Gmail
GoogleAuth() {
return this.AuthLogin(new auth.GoogleAuthProvider());
}
// Auth providers
AuthLogin(provider: any) {
return this.ngFireAuth
.signInWithPopup(provider)
.then((result) => {
this.ngZone.run(() => {
this.router.navigate(['dashboard']);
});
this.SetUserData(result.user);
})
.catch((error) => {
window.alert(error);
});
}
// Store user in localStorage
SetUserData(user: any) {
const userRef: AngularFirestoreDocument<any> = this.afStore.doc(
`users/${user.uid}`
);
const userData: User = {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL,
emailVerified: user.emailVerified,
};
return userRef.set(userData, {
merge: true,
});
}
// Sign-out
SignOut() {
return this.ngFireAuth.signOut().then(() => {
localStorage.removeItem('user');
this.router.navigate(['login']);
});
}
}
And then i have tab1.page.ts as follow
import { FirebaseModule } from '../firebase/firebase.module';
import { AuthenticationServiceService } from '../authentication-service.service';
@Component({
selector: 'app-tab1',
templateUrl: 'tab1.page.html',
styleUrls: ['tab1.page.scss'],
standalone: true,
imports: [IonicModule, CommonModule, FirebaseModule, FormsModule, ReactiveFormsModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class Tab1Page {
constructor(public authService: AuthenticationServiceService) {}
the error i get is below
ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(Standalone[Tab1Page])[AuthenticationServiceService -> AuthenticationServiceService -> AuthenticationServiceService -> AuthenticationServiceService -> AngularFirestore -> InjectionToken angularfire2.app.options -> InjectionToken angularfire2.app.options]:
NullInjectorError: No provider for InjectionToken angularfire2.app.options!
NullInjectorError: R3InjectorError(Standalone[Tab1Page])[AuthenticationServiceService -> AuthenticationServiceService -> AuthenticationServiceService -> AuthenticationServiceService -> AngularFirestore -> InjectionToken angularfire2.app.options -> InjectionToken angularfire2.app.options]:
NullInjectorError: No provider for InjectionToken angularfire2.app.options!
at NullInjector.get (core.mjs:7493:27)
at R3Injector.get (core.mjs:7914:33)
at R3Injector.get (core.mjs:7914:33)
at injectInjectorOnly (core.mjs:618:33)
at Module.ɵɵinject (core.mjs:622:60)
at Object.AngularFirestore_Factory [as factory] (angular-fire-compat-firestore.js:584:102)
at R3Injector.hydrate (core.mjs:8015:35)
at R3Injector.get (core.mjs:7903:33)
at injectInjectorOnly (core.mjs:618:33)
at Module.ɵɵinject (core.mjs:622:60)
at resolvePromise (zone.js:1211:31)
at resolvePromise (zone.js:1165:17)
at zone.js:1278:17
at _ZoneDelegate.invokeTask (zone.js:406:31)
at core.mjs:23896:55
at AsyncStackTaggingZoneSpec.onInvokeTask (core.mjs:23896:36)
at _ZoneDelegate.invokeTask (zone.js:405:60)
at Object.onInvokeTask (core.mjs:24197:33)
at _ZoneDelegate.invokeTask (zone.js:405:60)
at Zone.runTask (zone.js:178:47)
2
Answers
I’m having this exact same problem and i got a lot of issues trying to solve it. Now i can login with Google popup but i’m having CORS issues not sure why. I think your problem is how you are trying to access to Auth. Found this example and it worked for me except for the CORS problem
Could you try creating an AuthenticationModule that provides an AuthenticationService and imports FirebaseModule, and then importing AuthenticationModule to Tab1Page instead of FirebaseModule?