skip to Main Content

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


  1. 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

    import { Injectable, inject } from '@angular/core';
    import { GoogleAuthProvider, signInWithPopup } from 'firebase/auth';
    import { Auth } from '@angular/fire/auth';
    @Injectable({
      providedIn: 'root'
    })
    export class AuthService {
      private auth: Auth = inject(Auth);
      constructor() { }
      // Sign in using a popup.
      async signWithGoogle() {
        const provider = new GoogleAuthProvider();
        provider.addScope('profile');
        provider.addScope('email');
        const result = await signInWithPopup(this.auth, provider);
    
        const user = result.user;
        const credential = GoogleAuthProvider.credentialFromResult(result);
        const token = credential?.accessToken;
        console.log(user);
        console.log(token);
      }
    }
    Login or Signup to reply.
  2. Could you try creating an AuthenticationModule that provides an AuthenticationService and imports FirebaseModule, and then importing AuthenticationModule to Tab1Page instead of FirebaseModule?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search