英文:
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 '@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)
答案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 '@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);
}
}
<!-- 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?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论