Angular 17独立模式下InjectionToken angularfire2.app.options提供者缺失错误
解决Angular 17独立模式下Firebase注入错误:
NullInjectorError: No provider for InjectionToken angularfire2.app.options! 问题原因
你在独立模式下同时混用了AngularFire的新API提供者(provideFirebaseApp等)和compat兼容包(@angular/fire/compat/firestore),两者依赖的注入令牌不匹配,导致找不到angularfire2.app.options的提供者。另外,你在standalone组件的imports数组中导入了AngularFireModule等NgModule,这不符合独立组件的使用规范。
解决方案
方案1:修复Compat包配置(保留现有服务代码)
如果想继续使用当前基于compat包的服务代码,按以下步骤调整:
- 修改
app.config.ts,替换为Compat版本的Firebase提供者
import { ApplicationConfig, importProvidersFrom } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; import { provideClientHydration } from '@angular/platform-browser'; // 导入Compat版本的Firebase模块 import { AngularFireModule } from '@angular/fire/compat'; import { AngularFirestoreModule } from '@angular/fire/compat/firestore'; import { AngularFireStorageModule } from '@angular/fire/compat/storage'; // 导入Toastr和动画提供者 import { provideAnimations } from '@angular/platform-browser/animations'; import { provideToastr } from 'ngx-toastr'; export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), provideClientHydration(), // 用Compat模块初始化Firebase importProvidersFrom( AngularFireModule.initializeApp({ // 你的Firebase配置信息 }) ), importProvidersFrom(AngularFirestoreModule), importProvidersFrom(AngularFireStorageModule), // 配置Toastr和动画 provideAnimations(), provideToastr({ timeOut: 3000, positionClass: 'toast-top-right', preventDuplicates: true }) ] };
- 清理
app.component.ts的imports数组
移除所有NgModule类型的导入,仅保留独立组件和内置指令:
import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import { ListarTarjetaComponent } from './components/listar-tarjeta/listar-tarjeta.component'; import { CrearTarjetaComponent } from './components/crear-tarjeta/crear-tarjeta.component'; @Component({ selector: 'app-root', standalone: true, imports: [ RouterOutlet, ListarTarjetaComponent, CrearTarjetaComponent ], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { title = 'tarjetacreditoangular'; }
方案2:迁移到AngularFire新API(适配Angular 17独立模式)
如果想使用AngularFire最新API(无需compat包),按以下步骤修改:
- 保留
app.config.ts的现有新API配置
你的app.config.ts中provideFirebaseApp、provideFirestore等配置无需修改,只需添加Toastr和动画提供者:
import { provideAnimations } from '@angular/platform-browser/animations'; import { provideToastr } from 'ngx-toastr'; // 将以下内容加入providers数组 provideAnimations(), provideToastr({ timeOut: 3000, positionClass: 'toast-top-right', preventDuplicates: true })
- 修改
tarjeta.service.ts为新API实现
替换compat包的Firestore调用为最新API:
import { Injectable, inject } from '@angular/core'; import { Firestore, collection, addDoc, collectionData, deleteDoc, doc, updateDoc, orderBy, query } from '@angular/fire/firestore'; import { TarjetaCredito } from '../models/tarjeta-credito/tarjeta-credito.module'; import { Observable, Subject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class TarjetaService { private tarjeta$ = new Subject<any>(); private firestore = inject(Firestore); private tarjetasCollection = collection(this.firestore, 'tarjetas'); guardarTarjeta(tarjeta: TarjetaCredito): Promise<any> { return addDoc(this.tarjetasCollection, tarjeta); } obtenerTarjetas(): Observable<any> { const q = query(this.tarjetasCollection, orderBy('fechaCreacion', 'asc')); // idField自动将文档ID添加到返回结果中 return collectionData(q, { idField: 'id' }); } eliminarTarjeta(id: string): Promise<any> { const tarjetaDoc = doc(this.firestore, `tarjetas/${id}`); return deleteDoc(tarjetaDoc); } editarTarjeta(id: string, tarjeta: any): Promise<any> { const tarjetaDoc = doc(this.firestore, `tarjetas/${id}`); return updateDoc(tarjetaDoc, tarjeta); } addTarjetaEdit(tarjeta: TarjetaCredito) { this.tarjeta$.next(tarjeta); } getTarjetaEdit(): Observable<TarjetaCredito> { return this.tarjeta$.asObservable(); } }
- 同样清理
app.component.ts的imports数组
移除AngularFireModule、ToastrModule等NgModule导入,仅保留独立组件和内置指令。
总结
- 方案1适合快速修复现有代码,无需修改服务逻辑;
- 方案2更符合Angular 17独立组件的设计理念,也是Firebase官方推荐的最新使用方式,推荐长期采用。
内容的提问来源于stack exchange,提问作者Agustín Andres Gonzalez
相关产品推荐
相关产品推荐

