angular fire auth with ionic 7 causes NullInjectorError: No provider for InjectionToken angularfire2.app.options

huangapple go评论72阅读模式
英文:

angular fire auth with ionic 7 causes NullInjectorError: No provider for InjectionToken angularfire2.app.options

问题

以下是您提供的代码的翻译部分:

firebase.module.ts

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 { }

authentication-service.service.ts

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 logged 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']);
    });
  }
}

tab1.page.ts

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) {}
}

请注意,以上是您提供的代码的翻译部分,未包含具体问题或错误的解决方案。如有需要,请提出具体问题,我会尽力提供帮助。

英文:

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 &#39;@angular/core&#39;;
import { CommonModule } from &#39;@angular/common&#39;;
import { initializeApp, provideFirebaseApp } from &#39;@angular/fire/app&#39;;
import { provideAuth, getAuth } from &#39;@angular/fire/auth&#39;;
import { provideFirestore, getFirestore } from &#39;@angular/fire/firestore&#39;;
// Your web app&#39;s Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: &quot;XXXXX&quot;,
...
};
@NgModule({
declarations: [],
imports: [
CommonModule,
provideFirebaseApp(
() =&gt; initializeApp(firebaseConfig)), 
provideAuth(() =&gt; getAuth()), 
provideFirestore(() =&gt; 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 &#39;@angular/core&#39;;
import {
AngularFirestore,
AngularFirestoreDocument,
} from &#39;@angular/fire/compat/firestore&#39;;
import { AngularFireAuth } from &#39;@angular/fire/compat/auth&#39;;
import { Router } from &#39;@angular/router&#39;;
import { User } from &#39;./modal/user.modal&#39;;
import * as auth from &#39;firebase/auth&#39;;
@Injectable({
providedIn: &#39;root&#39;
})
export class AuthenticationServiceService {
userData: any;
constructor( public afStore: AngularFirestore,
public ngFireAuth: AngularFireAuth,
public router: Router,
public ngZone: NgZone) {
this.ngFireAuth.authState.subscribe((user) =&gt; {
if (user) {
this.userData = user;
localStorage.setItem(&#39;user&#39;, JSON.stringify(this.userData));
JSON.parse(localStorage.getItem(&#39;user&#39;) || &#39;{}&#39;);
} else {
localStorage.setItem(&#39;user&#39;, null || &#39;{}&#39;);
JSON.parse(localStorage.getItem(&#39;user&#39;) || &#39;{}&#39;);
}
});
}
// Returns true when user is looged in
get isLoggedIn(): boolean {
const user = JSON.parse(localStorage.getItem(&#39;user&#39;) || &#39;{}&#39;);
return user !== null &amp;&amp; user.emailVerified !== false ? true : false;
}
// Returns true when user&#39;s email is verified
get isEmailVerified(): boolean {
const user = JSON.parse(localStorage.getItem(&#39;user&#39;) || &#39;{}&#39;);
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) =&gt; {
this.ngZone.run(() =&gt; {
this.router.navigate([&#39;dashboard&#39;]);
});
this.SetUserData(result.user);
})
.catch((error) =&gt; {
window.alert(error);
});
}
// Store user in localStorage
SetUserData(user: any) {
const userRef: AngularFirestoreDocument&lt;any&gt; = 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(() =&gt; {
localStorage.removeItem(&#39;user&#39;);
this.router.navigate([&#39;login&#39;]);
});
}
}

And then i have tab1.page.ts as follow

import { FirebaseModule } from &#39;../firebase/firebase.module&#39;;
import { AuthenticationServiceService } from &#39;../authentication-service.service&#39;;
@Component({
selector: &#39;app-tab1&#39;,
templateUrl: &#39;tab1.page.html&#39;,
styleUrls: [&#39;tab1.page.scss&#39;],
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 -&gt; AuthenticationServiceService -&gt; AuthenticationServiceService -&gt; AuthenticationServiceService -&gt; AngularFirestore -&gt; InjectionToken angularfire2.app.options -&gt; InjectionToken angularfire2.app.options]: 
NullInjectorError: No provider for InjectionToken angularfire2.app.options!
NullInjectorError: R3InjectorError(Standalone[Tab1Page])[AuthenticationServiceService -&gt; AuthenticationServiceService -&gt; AuthenticationServiceService -&gt; AuthenticationServiceService -&gt; AngularFirestore -&gt; InjectionToken angularfire2.app.options -&gt; 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)

答案1

得分: 2

我遇到了完全相同的问题,并尝试解决它时遇到了很多问题。现在我可以通过Google弹出窗口登录,但我遇到了跨源资源共享(CORS)问题,不确定原因。我认为您的问题在于您尝试访问Auth的方式。我找到了这个示例,对我有用,除了CORS问题。

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() { }
  // 使用弹出窗口登录。
  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);
  }
}

请注意,此处未提供完整的解决方案,仅提供了代码部分的翻译。如果您需要更多帮助解决CORS问题或其他问题,请提供更多详细信息,以便我能够为您提供更多指导。

英文:

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

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

import { Injectable, inject } from &#39;@angular/core&#39;;
import { GoogleAuthProvider, signInWithPopup } from &#39;firebase/auth&#39;;
import { Auth } from &#39;@angular/fire/auth&#39;;
@Injectable({
providedIn: &#39;root&#39;
})
export class AuthService {
private auth: Auth = inject(Auth);
constructor() { }
// Sign in using a popup.
async signWithGoogle() {
const provider = new GoogleAuthProvider();
provider.addScope(&#39;profile&#39;);
provider.addScope(&#39;email&#39;);
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);
}
}

<!-- end snippet -->

答案2

得分: 0

你可以尝试创建一个提供身份验证服务的AuthenticationModule,然后导入FirebaseModule,并将AuthenticationModule导入Tab1Page,而不是FirebaseModule。

英文:

Could you try creating an AuthenticationModule that provides an AuthenticationService and imports FirebaseModule, and then importing AuthenticationModule to Tab1Page instead of FirebaseModule?

huangapple
  • 本文由 发表于 2023年6月18日 23:54:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76501376.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定