【问题标题】:NullInjectorError: No provider for InjectionToken angularfire2.app.options! 2021NullInjectorError:没有 InjectionToken angularfire2.app.options 的提供者! 2021
【发布时间】:2021-12-18 23:56:36
【问题描述】:

好的,我刚开始使用 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!

以下链接到目前为止还没有帮助

Link1Link2Link3

app.module.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 { }

login.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"}
        });
  }

}

login.component.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);
      }
    });
  }

}

package.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"
  }
}

【问题讨论】:

    标签: firebase firebase-authentication angularfire2


    【解决方案1】:

    我今天遇到了同样的问题,我同意:有很多版本,他们的文档令人失望。

    解决方案(以我为例)

    对于我的设置(角度 11 + 角度/火 6.1.5),我必须将以下内容放入我的 app.module.ts 文件中:

    ...
        imports: [
            ...
            AngularFireModule.initializeApp(environment.firebase),
        ],
    ...
    
    

    (对我来说,environment.firebase 包含我的 firebase 配置。)

    下面问题进一步分析,不介意的可以停止阅读

    angular/fire 7 的文档会告诉你这样做:

    provideFirebaseApp(() => initializeApp(environment.firebase)),
    

    我确信这对第 7 版非常有用,但 Angular 11 会自动安装第 6 版,因为它是兼容的。

    【讨论】:

    • 谢谢!,我会看看降级 Angular 版本是否有帮助
    • 同样的错误,使用 Angular 13.1.1 和 Fire 7.2.0 和 AngularFire 的默认骨架初始化的相同解决方案。
    【解决方案2】:

    按照@Daniel Eisenhardt 的建议,我降级了我的 Angular 版本。它现在正在工作!角度:~11.2.4 并运行 ng add @angular/fire 安装了兼容版本的 angular fire。 ("^6.1.5") 这是我更新的文件

    app.module.ts

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule, ReactiveFormsModule } from '@angular/forms';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    import { HomeComponent } from './component/home/home.component';
    import { LoginComponent } from './component/login/login.component';
    import { NotFoundComponent } from './component/not-found/not-found.component';
    
    import { AngularFireModule } from '@angular/fire';
    import { AngularFirestoreModule } from '@angular/fire/firestore';
    import { AngularFireDatabaseModule } from '@angular/fire/database';
    // import { AngularFireStorageModule } from '@angular/fire/storage';
    import { environment } from '../environments/environment';
    
    @NgModule({
      declarations: [
        AppComponent,
        HomeComponent,
        LoginComponent,
        NotFoundComponent
      ],
      imports: [
        BrowserModule,
        AppRoutingModule,
        AngularFireModule.initializeApp(environment.firebase)
        AngularFirestoreModule,                                   
        AngularFireDatabaseModule,
        FormsModule,
        ReactiveFormsModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    



    package.json

    {
      "name": "evnt-mgmnt-app",
      "version": "0.0.0",
      "scripts": {
        "ng": "ng",
        "start": "ng serve",
        "build": "ng build",
        "test": "ng test",
        "lint": "ng lint",
        "e2e": "ng e2e"
      },
      "private": true,
      "dependencies": {
        "@angular/animations": "~11.2.14",
        "@angular/common": "~11.2.14",
        "@angular/compiler": "~11.2.14",
        "@angular/core": "~11.2.14",
        "@angular/fire": "^6.1.5",
        "@angular/forms": "~11.2.14",
        "@angular/platform-browser": "~11.2.14",
        "@angular/platform-browser-dynamic": "~11.2.14",
        "@angular/router": "~11.2.14",
        "rxjs": "~6.6.0",
        "tslib": "^2.0.0",
        "zone.js": "~0.11.3",
        "firebase": "^7.0 || ^8.0"
      },
      "devDependencies": {
        "@angular-devkit/build-angular": "~0.1102.13",
        "@angular/cli": "~11.2.15",
        "@angular/compiler-cli": "~11.2.14",
        "@types/jasmine": "~3.6.0",
        "@types/node": "^12.11.1",
        "codelyzer": "^6.0.0",
        "jasmine-core": "~3.6.0",
        "jasmine-spec-reporter": "~5.0.0",
        "karma": "~6.1.0",
        "karma-chrome-launcher": "~3.1.0",
        "karma-coverage": "~2.0.3",
        "karma-jasmine": "~4.0.0",
        "karma-jasmine-html-reporter": "~1.5.0",
        "protractor": "~7.0.0",
        "ts-node": "~8.3.0",
        "tslint": "~6.1.0",
        "typescript": "~4.1.5",
        "@angular-devkit/architect": ">= 0.900 < 0.1300",
        "firebase-tools": "^8.0.0 || ^9.0.0",
        "fuzzy": "^0.1.3",
        "inquirer": "^6.2.2",
        "inquirer-autocomplete-prompt": "^1.0.1",
        "open": "^7.0.3",
        "jsonc-parser": "^3.0.0"
      }
    }
    

    【讨论】:

      【解决方案3】:

      似乎 AngularFire 正在进行包含 Firebase 的新模块化 API 的重大更改,但文档还没有完全跟上。要点是您正在使用新 API 初始化 Firebase 应用程序,但尝试将 Firebase 资源与旧 API 一起使用。

      关键是看import语句。比较新旧应用的初始化方式:

      import {AngularFireModule} from '@angular/fire/compat';
      
      [...]
      
      imports: [
          AngularFireModule.initializeApp(environment.firebase),
      ]
      

      对比

      import {initializeApp, provideFirebaseApp} from '@angular/fire/app';
      
      [...]
      
      imports: [
          provideFirebaseApp( () => initializeApp(environment.firebase)),
      ]
      

      注意旧式初始化是如何在“compat”命名空间下进行的。如果您以这种方式初始化您的应用,您必须还使用兼容库来访问资源。比如来自AngularFire docs

      import {AngularFirestore, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
      
      [...]
      
      constructor(private afs: AngularFirestore) {
          this.itemDoc = afs.doc<Item>('items/1');
          this.item = this.itemDoc.valueChanges();
        }
      

      但是,这不适用于新样式的应用程序初始化。相反,您必须使用类似这样的东西,改编自 Firebase docs:

      import {doc, Firestore, getDoc} from '@angular/fire/firestore';
      
      [...]
      
      constructor(private firestore: Firestore) { }
      
      [...]
      
      const docRef = doc(this.firestore, "cities", "SF");
      const docSnap = await getDoc(docRef);
      

      为什么重要?我假设但不知道该应用程序的实例不在新旧之间共享。

      所以,故事的寓意:

      • Internet 上的大多数文档都使用旧 API。如果您想使用该 API,请使用库的“兼容”版本。
      • 如果您想使用现代模块化 API,请确保您使用“compat”库。最好的办法是在 AngularFire 团队有机会赶上之前参考 Firebase 文档。

      【讨论】:

        猜你喜欢
        • 2021-12-15
        • 2019-05-19
        • 1970-01-01
        • 2018-07-16
        • 2018-10-19
        • 1970-01-01
        • 2019-08-10
        • 2021-09-08
        • 1970-01-01
        相关资源
        最近更新 更多