angularfirebaseionic-framework

How do I fix the Ionic Angular Standalone Firebase API called outside injection context error?


While migrating my Ionic Firebase project from NgModules to standalone, I get errors - I'm using Ionic Capacitor 7, Angular 20.

ERROR: Firebase API called outside injection context: user

Has anyone else had this issue? Most forums suggest turning off the error, but I feel that would be dangerous to ignore.

app.module.ts // works fine

import { NgModule, isDevMode } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { provideHttpClient ,HttpClient, HttpHeaders, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
import { getStorage, provideStorage } from '@angular/fire/storage';
import { environment } from '../environments/environment';
import { Capacitor } from '@capacitor/core';
import {
  getAuth,
  indexedDBLocalPersistence,
  initializeAuth,
  provideAuth,
} from '@angular/fire/auth';
import { ServiceWorkerModule } from '@angular/service-worker';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule, 
    IonicModule.forRoot(), 
    AppRoutingModule, 
    provideFirebaseApp(() => initializeApp(environment.firebase)), 
    provideAuth(() => {
      if (Capacitor.isNativePlatform()) {
        return initializeAuth(getApp(), {  persistence: indexedDBLocalPersistence });
      } 
      else { return getAuth() }
    }),
    provideFirestore(() => getFirestore()), 
    provideStorage(() => getStorage()), ServiceWorkerModule.register('ngsw-worker.js', {
      enabled: !isDevMode(),
      registrationStrategy: 'registerWhenStable:30000'
    }),
  ],
  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
  bootstrap: [AppComponent],
})
export class AppModule {}

main.ts:

// Firebase API called outside injection context error

import { enableProdMode, importProvidersFrom } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { RouteReuseStrategy, provideRouter, withPreloading, PreloadAllModules } from '@angular/router';
import { routes } from './app/app.routes';
import { AppComponent } from './app/app.component';
import { isDevMode } from '@angular/core';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
import { getStorage, provideStorage } from '@angular/fire/storage';
import { environment } from './environments/environment';
import { Capacitor } from '@capacitor/core';
import {
  getAuth,
  indexedDBLocalPersistence,
  initializeAuth,
  provideAuth
} from '@angular/fire/auth';
import {
  IonicRouteStrategy,
  provideIonicAngular
} from '@ionic/angular/standalone';
import { provideServiceWorker } from '@angular/service-worker';

bootstrapApplication(AppComponent, {
  providers: [
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    provideIonicAngular(), // provideIonicAngular({ mode: 'ios' }),
    provideRouter(routes, withPreloading(PreloadAllModules)),
    provideFirebaseApp(() => initializeApp(environment.firebase)),
    provideAuth(() => {
      if (Capacitor.isNativePlatform()) {
        return initializeAuth(getApp(), {  persistence: indexedDBLocalPersistence });
      } 
      else { return getAuth() }
    }),
    provideFirestore(() => getFirestore()), 
    provideStorage(() => getStorage()),
    provideHttpClient(withInterceptorsFromDi()), 
    provideServiceWorker('ngsw-worker.js', {
      enabled: !isDevMode(),
      registrationStrategy: 'registerWhenStable:30000'
    }),
  ]
});

Solution

  • Here is how I got the the warnings to disappear by using runInInjectionContext to wrap anything using @angular/fire/firestore
    
    import { Component, inject, Injector, runInInjectionContext } from '@angular/core';
    import { collection, collectionData, Firestore, where, query } from '@angular/fire/firestore';
    import { Auth } from '@angular/fire/auth';
    import { Subscription } from 'rxjs';
    
    constructor( private injector: Injector, private auth: Auth ) {}
    
          getUserList() {
            runInInjectionContext(this.injector, () => {
              const firestore: Firestore = inject(Firestore);
              const col = collection(this.firestore, 'users');
              const usersQuery = query( col );
              const collectionSub = collectionData(usersQuery, { idField: 'id'});
              this.tasksSub = collectionSub.subscribe((users) => { 
              const user = users.filter((x: any) => x.uid === this.auth.currentUser?.uid); 
              this.getContactGroups(user[0]['company']);
             });
            });
          }