Ven*_*enn 23 firebase firebase-authentication angularfire2
好吧,我刚刚开始使用 Angular Firebase,我已经挠头两天了。大多数教程主要针对旧版本的 firebase
这是我将身份验证服务注入组件时收到的错误
Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[LoginService -> AngularFireAuth -> InjectionToken angularfire2.app.options -> InjectionToken angularfire2.app.options -> InjectionToken angularfire2.app.options]:
NullInjectorError: No provider for InjectionToken angularfire2.app.options!
NullInjectorError: R3InjectorError(AppModule)[LoginService -> AngularFireAuth -> InjectionToken angularfire2.app.options -> InjectionToken angularfire2.app.options -> InjectionToken angularfire2.app.options]:
NullInjectorError: No provider for InjectionToken angularfire2.app.options!
Run Code Online (Sandbox Code Playgroud)
到目前为止,以下链接没有帮助
应用程序模块.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { LoginService } from 'src/services/login.service';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './components/login/login.component';
import { HomeComponent } from './components/home/home.component';
import { NotFoundComponent } from './components/not-found/not-found.component';
import { environment } from '../environments/environment';
import { initializeApp,provideFirebaseApp } from '@angular/fire/app';
import { provideAuth,getAuth } from '@angular/fire/auth';
import { provideDatabase,getDatabase } from '@angular/fire/database';
import { provideFirestore,getFirestore } from '@angular/fire/firestore';
import { AngularFirestore } from '@angular/fire/compat/firestore';
@NgModule({
declarations: [
AppComponent,
LoginComponent,
HomeComponent,
NotFoundComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAuth(() => getAuth()),
provideDatabase(() => getDatabase()),
provideFirestore(() => getFirestore()),
FormsModule,
ReactiveFormsModule
],
providers: [LoginService],
bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
登录.service.ts
import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import { Router } from '@angular/router';
import { AngularFirestore } from '@angular/fire/compat/firestore';
@Injectable({
providedIn: 'root'
})
export class LoginService {
userLoggedIn: boolean;
constructor(private afAuth: AngularFireAuth, private router : Router, private afs: AngularFirestore) {
this.userLoggedIn = false;
}
loginUser(email: string, password: string): Promise<any> {
return this.afAuth.signInWithEmailAndPassword(email,password)
.then(() => {
console.log('Auth Service: loginUser: success');
this.router.navigate(['']);
})
.catch(error => {
console.log('Auth Service: login error...');
console.log('error code', error.code);
console.log('error', error);
if (error.code)
return { isValid: false, message: error.message };
else
return { isValid: false, message : "Login Error"}
});
}
}
Run Code Online (Sandbox Code Playgroud)
登录.组件.ts
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { LoginService } from 'src/services/login.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
loginFormCtrl: FormGroup;
constructor(private LoginService: LoginService, private router: Router) {
this.loginFormCtrl = new FormGroup({
email: new FormControl('', Validators.required),
password: new FormControl(null, Validators.required)
})
}
ngOnInit(): void {
}
onLogin() {
if (this.loginFormCtrl.invalid)
return;
this.LoginService.loginUser(this.loginFormCtrl.value.email, this.loginFormCtrl.value.password).then((result) => {
if (result == null) {
console.log('logging in...');
this.router.navigate(['']);
}
else if (result.isValid == false) {
console.log('login error', result);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
包.json
{
"name": "fire-base",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "~12.2.0",
"@angular/common": "~12.2.0",
"@angular/compiler": "~12.2.0",
"@angular/core": "~12.2.0",
"@angular/fire": "^7.1.1",
"@angular/forms": "~12.2.0",
"@angular/platform-browser": "~12.2.0",
"@angular/platform-browser-dynamic": "~12.2.0",
"@angular/router": "~12.2.0",
"rxjs": "~6.6.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4",
"firebase": "^9.1.0",
"rxfire": "^6.0.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "~12.2.7",
"@angular/cli": "~12.2.7",
"@angular/compiler-cli": "~12.2.0",
"@types/jasmine": "~3.8.0",
"@types/node": "^12.11.1",
"jasmine-core": "~3.8.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.3.5"
}
}
Run Code Online (Sandbox Code Playgroud)
Bar*_*abi 31
修复实际上非常简单......
在你的app.module.ts中
进口
import { FIREBASE_OPTIONS } from '@angular/fire/compat';
Run Code Online (Sandbox Code Playgroud)
然后将其添加到提供者中
providers: [
{ provide: FIREBASE_OPTIONS, useValue: environment.firebase }
],
Run Code Online (Sandbox Code Playgroud)
Mic*_*oto 18
AngularFire 似乎正处于采用 Firebase 新模块化 API 的重大变化之中,但文档还没有完全跟上。要点是,您正在使用新 API 初始化 Firebase 应用程序,但尝试通过旧 API 使用 Firebase 资源。
关键是看import语句。比较新旧方式的应用程序初始化:
import {AngularFireModule} from '@angular/fire/compat';
[...]
imports: [
AngularFireModule.initializeApp(environment.firebase),
]
Run Code Online (Sandbox Code Playgroud)
与
import {initializeApp, provideFirebaseApp} from '@angular/fire/app';
[...]
imports: [
provideFirebaseApp( () => initializeApp(environment.firebase)),
]
Run Code Online (Sandbox Code Playgroud)
请注意旧式初始化是如何在“compat”命名空间下进行的。如果您以这种方式初始化应用程序,则还必须使用兼容库来访问资源。例如,来自AngularFire 文档:
import {AngularFirestore, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
[...]
constructor(private afs: AngularFirestore) {
this.itemDoc = afs.doc<Item>('items/1');
this.item = this.itemDoc.valueChanges();
}
Run Code Online (Sandbox Code Playgroud)
但是,这不适用于新样式应用程序初始化。相反,您必须使用类似的内容,改编自Firebase 文档:
import {doc, Firestore, getDoc} from '@angular/fire/firestore';
[...]
constructor(private firestore: Firestore) { }
[...]
const docRef = doc(this.firestore, "cities", "SF");
const docSnap = await getDoc(docRef);
Run Code Online (Sandbox Code Playgroud)
为什么这有关系?我假设但不知道该应用程序的实例不在新旧之间共享。
所以,这个故事的寓意是:
我今天遇到了同样的问题,我同意:有很多版本,而且它们的文档令人失望。
解决方案(就我而言)
对于我的设置(Angular 11 + Angular/Fire 6.1.5),我必须将以下内容放入我的app.module.ts文件中:
...
imports: [
...
AngularFireModule.initializeApp(environment.firebase),
],
...
Run Code Online (Sandbox Code Playgroud)
(对我来说environment.firebase包含我的 firebase 配置。)
下面进一步分析问题,不介意的可以停止阅读
Angular/Fire 7 的文档会告诉你这样做:
provideFirebaseApp(() => initializeApp(environment.firebase)),
Run Code Online (Sandbox Code Playgroud)
我确信这对于版本 7 非常有效,但 Angular 11 会自动安装版本 6,因为它是兼容的。
小智 5
当我使用两个版本的初始化时,我的问题得到了解决
AngularFireModule.initializeApp(environment.firebase),
provideFirebaseApp(() => initializeApp(environment.firebase)),
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13162 次 |
| 最近记录: |