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

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

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

问题

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

firebase.module.ts

  1. import { NgModule } from '@angular/core';
  2. import { CommonModule } from '@angular/common';
  3. import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
  4. import { provideAuth, getAuth } from '@angular/fire/auth';
  5. import { provideFirestore, getFirestore } from '@angular/fire/firestore';
  6. // Your web app's Firebase configuration
  7. // For Firebase JS SDK v7.20.0 and later, measurementId is optional
  8. const firebaseConfig = {
  9. apiKey: "XXXXX",
  10. // ...
  11. };
  12. @NgModule({
  13. declarations: [],
  14. imports: [
  15. CommonModule,
  16. provideFirebaseApp(() => initializeApp(firebaseConfig)),
  17. provideAuth(() => getAuth()),
  18. provideFirestore(() => getFirestore()),
  19. ],
  20. providers: []
  21. })
  22. export class FirebaseModule { }

authentication-service.service.ts

  1. import { Injectable, NgZone } from '@angular/core';
  2. import {
  3. AngularFirestore,
  4. AngularFirestoreDocument,
  5. } from '@angular/fire/compat/firestore';
  6. import { AngularFireAuth } from '@angular/fire/compat/auth';
  7. import { Router } from '@angular/router';
  8. import { User } from './modal/user.modal';
  9. import * as auth from 'firebase/auth';
  10. @Injectable({
  11. providedIn: 'root'
  12. })
  13. export class AuthenticationServiceService {
  14. userData: any;
  15. constructor(
  16. public afStore: AngularFirestore,
  17. public ngFireAuth: AngularFireAuth,
  18. public router: Router,
  19. public ngZone: NgZone
  20. ) {
  21. this.ngFireAuth.authState.subscribe((user) => {
  22. if (user) {
  23. this.userData = user;
  24. localStorage.setItem('user', JSON.stringify(this.userData));
  25. JSON.parse(localStorage.getItem('user') || '{}');
  26. } else {
  27. localStorage.setItem('user', null || '{}');
  28. JSON.parse(localStorage.getItem('user') || '{}');
  29. }
  30. });
  31. }
  32. // Returns true when user is logged in
  33. get isLoggedIn(): boolean {
  34. const user = JSON.parse(localStorage.getItem('user') || '{}');
  35. return user !== null && user.emailVerified !== false ? true : false;
  36. }
  37. // Returns true when user's email is verified
  38. get isEmailVerified(): boolean {
  39. const user = JSON.parse(localStorage.getItem('user') || '{}');
  40. return user.emailVerified !== false ? true : false;
  41. }
  42. // Sign in with Gmail
  43. GoogleAuth() {
  44. return this.AuthLogin(new auth.GoogleAuthProvider());
  45. }
  46. // Auth providers
  47. AuthLogin(provider: any) {
  48. return this.ngFireAuth
  49. .signInWithPopup(provider)
  50. .then((result) => {
  51. this.ngZone.run(() => {
  52. this.router.navigate(['dashboard']);
  53. });
  54. this.SetUserData(result.user);
  55. })
  56. .catch((error) => {
  57. window.alert(error);
  58. });
  59. }
  60. // Store user in localStorage
  61. SetUserData(user: any) {
  62. const userRef: AngularFirestoreDocument<any> = this.afStore.doc(
  63. `users/${user.uid}`
  64. );
  65. const userData: User = {
  66. uid: user.uid,
  67. email: user.email,
  68. displayName: user.displayName,
  69. photoURL: user.photoURL,
  70. emailVerified: user.emailVerified,
  71. };
  72. return userRef.set(userData, {
  73. merge: true,
  74. });
  75. }
  76. // Sign-out
  77. SignOut() {
  78. return this.ngFireAuth.signOut().then(() => {
  79. localStorage.removeItem('user');
  80. this.router.navigate(['login']);
  81. });
  82. }
  83. }

tab1.page.ts

  1. import { FirebaseModule } from '../firebase/firebase.module';
  2. import { AuthenticationServiceService } from '../authentication-service.service';
  3. @Component({
  4. selector: 'app-tab1',
  5. templateUrl: 'tab1.page.html',
  6. styleUrls: ['tab1.page.scss'],
  7. standalone: true,
  8. imports: [IonicModule, CommonModule, FirebaseModule, FormsModule, ReactiveFormsModule],
  9. schemas: [CUSTOM_ELEMENTS_SCHEMA]
  10. })
  11. export class Tab1Page {
  12. constructor(public authService: AuthenticationServiceService) {}
  13. }

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

英文:

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

  1. import { NgModule } from &#39;@angular/core&#39;;
  2. import { CommonModule } from &#39;@angular/common&#39;;
  3. import { initializeApp, provideFirebaseApp } from &#39;@angular/fire/app&#39;;
  4. import { provideAuth, getAuth } from &#39;@angular/fire/auth&#39;;
  5. import { provideFirestore, getFirestore } from &#39;@angular/fire/firestore&#39;;
  6. // Your web app&#39;s Firebase configuration
  7. // For Firebase JS SDK v7.20.0 and later, measurementId is optional
  8. const firebaseConfig = {
  9. apiKey: &quot;XXXXX&quot;,
  10. ...
  11. };
  12. @NgModule({
  13. declarations: [],
  14. imports: [
  15. CommonModule,
  16. provideFirebaseApp(
  17. () =&gt; initializeApp(firebaseConfig)),
  18. provideAuth(() =&gt; getAuth()),
  19. provideFirestore(() =&gt; getFirestore(),
  20. ),
  21. ],
  22. providers: []
  23. })
  24. export class FirebaseModule { }

The auth service file looks like below

  1. //reference https://www.positronx.io/ionic-firebase-authentication-tutorial-with-examples/
  2. import { Injectable, NgZone } from &#39;@angular/core&#39;;
  3. import {
  4. AngularFirestore,
  5. AngularFirestoreDocument,
  6. } from &#39;@angular/fire/compat/firestore&#39;;
  7. import { AngularFireAuth } from &#39;@angular/fire/compat/auth&#39;;
  8. import { Router } from &#39;@angular/router&#39;;
  9. import { User } from &#39;./modal/user.modal&#39;;
  10. import * as auth from &#39;firebase/auth&#39;;
  11. @Injectable({
  12. providedIn: &#39;root&#39;
  13. })
  14. export class AuthenticationServiceService {
  15. userData: any;
  16. constructor( public afStore: AngularFirestore,
  17. public ngFireAuth: AngularFireAuth,
  18. public router: Router,
  19. public ngZone: NgZone) {
  20. this.ngFireAuth.authState.subscribe((user) =&gt; {
  21. if (user) {
  22. this.userData = user;
  23. localStorage.setItem(&#39;user&#39;, JSON.stringify(this.userData));
  24. JSON.parse(localStorage.getItem(&#39;user&#39;) || &#39;{}&#39;);
  25. } else {
  26. localStorage.setItem(&#39;user&#39;, null || &#39;{}&#39;);
  27. JSON.parse(localStorage.getItem(&#39;user&#39;) || &#39;{}&#39;);
  28. }
  29. });
  30. }
  31. // Returns true when user is looged in
  32. get isLoggedIn(): boolean {
  33. const user = JSON.parse(localStorage.getItem(&#39;user&#39;) || &#39;{}&#39;);
  34. return user !== null &amp;&amp; user.emailVerified !== false ? true : false;
  35. }
  36. // Returns true when user&#39;s email is verified
  37. get isEmailVerified(): boolean {
  38. const user = JSON.parse(localStorage.getItem(&#39;user&#39;) || &#39;{}&#39;);
  39. return user.emailVerified !== false ? true : false;
  40. }
  41. // Sign in with Gmail
  42. GoogleAuth() {
  43. return this.AuthLogin(new auth.GoogleAuthProvider());
  44. }
  45. // Auth providers
  46. AuthLogin(provider: any) {
  47. return this.ngFireAuth
  48. .signInWithPopup(provider)
  49. .then((result) =&gt; {
  50. this.ngZone.run(() =&gt; {
  51. this.router.navigate([&#39;dashboard&#39;]);
  52. });
  53. this.SetUserData(result.user);
  54. })
  55. .catch((error) =&gt; {
  56. window.alert(error);
  57. });
  58. }
  59. // Store user in localStorage
  60. SetUserData(user: any) {
  61. const userRef: AngularFirestoreDocument&lt;any&gt; = this.afStore.doc(
  62. `users/${user.uid}`
  63. );
  64. const userData: User = {
  65. uid: user.uid,
  66. email: user.email,
  67. displayName: user.displayName,
  68. photoURL: user.photoURL,
  69. emailVerified: user.emailVerified,
  70. };
  71. return userRef.set(userData, {
  72. merge: true,
  73. });
  74. }
  75. // Sign-out
  76. SignOut() {
  77. return this.ngFireAuth.signOut().then(() =&gt; {
  78. localStorage.removeItem(&#39;user&#39;);
  79. this.router.navigate([&#39;login&#39;]);
  80. });
  81. }
  82. }

And then i have tab1.page.ts as follow

  1. import { FirebaseModule } from &#39;../firebase/firebase.module&#39;;
  2. import { AuthenticationServiceService } from &#39;../authentication-service.service&#39;;
  3. @Component({
  4. selector: &#39;app-tab1&#39;,
  5. templateUrl: &#39;tab1.page.html&#39;,
  6. styleUrls: [&#39;tab1.page.scss&#39;],
  7. standalone: true,
  8. imports: [IonicModule, CommonModule, FirebaseModule, FormsModule, ReactiveFormsModule],
  9. schemas: [CUSTOM_ELEMENTS_SCHEMA]
  10. })
  11. export class Tab1Page {
  12. constructor(public authService: AuthenticationServiceService) {}

the error i get is below

  1. 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]:
  2. NullInjectorError: No provider for InjectionToken angularfire2.app.options!
  3. NullInjectorError: R3InjectorError(Standalone[Tab1Page])[AuthenticationServiceService -&gt; AuthenticationServiceService -&gt; AuthenticationServiceService -&gt; AuthenticationServiceService -&gt; AngularFirestore -&gt; InjectionToken angularfire2.app.options -&gt; InjectionToken angularfire2.app.options]:
  4. NullInjectorError: No provider for InjectionToken angularfire2.app.options!
  5. at NullInjector.get (core.mjs:7493:27)
  6. at R3Injector.get (core.mjs:7914:33)
  7. at R3Injector.get (core.mjs:7914:33)
  8. at injectInjectorOnly (core.mjs:618:33)
  9. at Module.ɵɵinject (core.mjs:622:60)
  10. at Object.AngularFirestore_Factory [as factory] (angular-fire-compat-firestore.js:584:102)
  11. at R3Injector.hydrate (core.mjs:8015:35)
  12. at R3Injector.get (core.mjs:7903:33)
  13. at injectInjectorOnly (core.mjs:618:33)
  14. at Module.ɵɵinject (core.mjs:622:60)
  15. at resolvePromise (zone.js:1211:31)
  16. at resolvePromise (zone.js:1165:17)
  17. at zone.js:1278:17
  18. at _ZoneDelegate.invokeTask (zone.js:406:31)
  19. at core.mjs:23896:55
  20. at AsyncStackTaggingZoneSpec.onInvokeTask (core.mjs:23896:36)
  21. at _ZoneDelegate.invokeTask (zone.js:405:60)
  22. at Object.onInvokeTask (core.mjs:24197:33)
  23. at _ZoneDelegate.invokeTask (zone.js:405:60)
  24. at Zone.runTask (zone.js:178:47)

答案1

得分: 2

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

  1. import { Injectable, inject } from '@angular/core';
  2. import { GoogleAuthProvider, signInWithPopup } from 'firebase/auth';
  3. import { Auth } from '@angular/fire/auth';
  4. @Injectable({
  5. providedIn: 'root'
  6. })
  7. export class AuthService {
  8. private auth: Auth = inject(Auth);
  9. constructor() { }
  10. // 使用弹出窗口登录。
  11. async signWithGoogle() {
  12. const provider = new GoogleAuthProvider();
  13. provider.addScope('profile');
  14. provider.addScope('email');
  15. const result = await signInWithPopup(this.auth, provider);
  16. const user = result.user;
  17. const credential = GoogleAuthProvider.credentialFromResult(result);
  18. const token = credential?.accessToken;
  19. console.log(user);
  20. console.log(token);
  21. }
  22. }

请注意,此处未提供完整的解决方案,仅提供了代码部分的翻译。如果您需要更多帮助解决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 -->

  1. import { Injectable, inject } from &#39;@angular/core&#39;;
  2. import { GoogleAuthProvider, signInWithPopup } from &#39;firebase/auth&#39;;
  3. import { Auth } from &#39;@angular/fire/auth&#39;;
  4. @Injectable({
  5. providedIn: &#39;root&#39;
  6. })
  7. export class AuthService {
  8. private auth: Auth = inject(Auth);
  9. constructor() { }
  10. // Sign in using a popup.
  11. async signWithGoogle() {
  12. const provider = new GoogleAuthProvider();
  13. provider.addScope(&#39;profile&#39;);
  14. provider.addScope(&#39;email&#39;);
  15. const result = await signInWithPopup(this.auth, provider);
  16. const user = result.user;
  17. const credential = GoogleAuthProvider.credentialFromResult(result);
  18. const token = credential?.accessToken;
  19. console.log(user);
  20. console.log(token);
  21. }
  22. }

<!-- 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:

确定