Skip to content

"Warning: Firebase API called outside injection context" on non-async functions #3611

Closed
@anisabboud

Description

@anisabboud

This is related to #3605 and #3607 where a workaround has been suggested #3590 (comment).
But my question is specifically for non-async functions.

First of all, thank you @jamesdaniels for the new guide at https://github.com/angular/angularfire/blob/main/docs/zones.md.
(I think the doc would benefit from some concrete examples.)

My understanding is that direct calls to docData where it's called say from within an rxjs switchMap, should be wrapped in runInInjectionContext

  loadDoc<T>(docPath: string): Observable<T | undefined> {
      return docData<T>(doc(this.firestore, docPath));
  }

↓↓↓

  private injectionContext = inject(EnvironmentInjector);

  loadDoc<T>(docPath: string): Observable<T | undefined> {
    return runInInjectionContext(this.injectionContext, () => {
      return docData<T>(doc(this.firestore, docPath));
    });
  }

However, even after adding runInInjectionContext wrappers for all load & set operations, there are still warnings from functions that are not async in nature such as where, snapToData, serverTimestamp, increment, orderBy, limit:

warnings on where, snapToData, serverTimestamp, increment, orderBy, limit

This is because tools/build.ts is applying ɵzoneWrap to every Firebase function:

export const collectionData = ɵzoneWrap(_collectionData, true);
export const docSnapshots = ɵzoneWrap(_doc, true);
export const docData = ɵzoneWrap(_docData, true);
export const fromRef = ɵzoneWrap(_fromRef, true);
export const snapToData = ɵzoneWrap(_snapToData, true);
export const sortedChanges = ɵzoneWrap(_sortedChanges, true);

export const addDoc = ɵzoneWrap(_addDoc, true);
export const aggregateFieldEqual = ɵzoneWrap(_aggregateFieldEqual, true);
export const aggregateQuerySnapshotEqual = ɵzoneWrap(_aggregateQuerySnapshotEqual, true);
export const and = ɵzoneWrap(_and, true);
export const arrayRemove = ɵzoneWrap(_arrayRemove, true);
export const arrayUnion = ɵzoneWrap(_arrayUnion, true);
export const average = ɵzoneWrap(_average, true);
export const clearIndexedDbPersistence = ɵzoneWrap(_clearIndexedDbPersistence, true);
export const collection = ɵzoneWrap(_collection, true);
export const collectionGroup = ɵzoneWrap(_collectionGroup, true);
export const connectFirestoreEmulator = ɵzoneWrap(_connectFirestoreEmulator, true);
export const count = ɵzoneWrap(_count, true);
export const deleteAllPersistentCacheIndexes = ɵzoneWrap(_deleteAllPersistentCacheIndexes, true);
export const deleteDoc = ɵzoneWrap(_deleteDoc, true);
export const deleteField = ɵzoneWrap(_deleteField, true);
export const disableNetwork = ɵzoneWrap(_disableNetwork, true);
export const disablePersistentCacheIndexAutoCreation = ɵzoneWrap(_disablePersistentCacheIndexAutoCreation, true);
export const doc = ɵzoneWrap(_doc, true);
export const documentId = ɵzoneWrap(_documentId, true);
export const enableIndexedDbPersistence = ɵzoneWrap(_enableIndexedDbPersistence, true);
export const enableMultiTabIndexedDbPersistence = ɵzoneWrap(_enableMultiTabIndexedDbPersistence, true);
export const enableNetwork = ɵzoneWrap(_enableNetwork, true);
export const enablePersistentCacheIndexAutoCreation = ɵzoneWrap(_enablePersistentCacheIndexAutoCreation, true);
export const endAt = ɵzoneWrap(_endAt, true);
export const endBefore = ɵzoneWrap(_endBefore, true);
export const getAggregateFromServer = ɵzoneWrap(_getAggregateFromServer, true);
export const getCountFromServer = ɵzoneWrap(_getCountFromServer, true);
export const getDoc = ɵzoneWrap(_getDoc, true);
export const getDocFromCache = ɵzoneWrap(_getDocFromCache, true);
export const getDocFromServer = ɵzoneWrap(_getDocFromServer, true);
export const getDocs = ɵzoneWrap(_getDocs, true);
export const getDocsFromCache = ɵzoneWrap(_getDocsFromCache, true);
export const getDocsFromServer = ɵzoneWrap(_getDocsFromServer, true);
export const getFirestore = ɵzoneWrap(_getFirestore, true);
export const getPersistentCacheIndexManager = ɵzoneWrap(_getPersistentCacheIndexManager, true);
export const increment = ɵzoneWrap(_increment, true);
export const initializeFirestore = ɵzoneWrap(_initializeFirestore, true);
export const limit = ɵzoneWrap(_limit, true);
export const limitToLast = ɵzoneWrap(_limitToLast, true);
export const loadBundle = ɵzoneWrap(_loadBundle, true);
export const memoryEagerGarbageCollector = ɵzoneWrap(_memoryEagerGarbageCollector, true);
export const memoryLocalCache = ɵzoneWrap(_memoryLocalCache, true);
export const memoryLruGarbageCollector = ɵzoneWrap(_memoryLruGarbageCollector, true);
export const namedQuery = ɵzoneWrap(_namedQuery, true);
export const onSnapshot = ɵzoneWrap(_onSnapshot, true);
export const onSnapshotsInSync = ɵzoneWrap(_onSnapshotsInSync, true);
export const or = ɵzoneWrap(_or, true);
export const orderBy = ɵzoneWrap(_orderBy, true);
export const persistentLocalCache = ɵzoneWrap(_persistentLocalCache, true);
export const persistentMultipleTabManager = ɵzoneWrap(_persistentMultipleTabManager, true);
export const persistentSingleTabManager = ɵzoneWrap(_persistentSingleTabManager, true);
export const query = ɵzoneWrap(_query, true);
export const queryEqual = ɵzoneWrap(_queryEqual, true);
export const refEqual = ɵzoneWrap(_refEqual, true);
export const runTransaction = ɵzoneWrap(_runTransaction, true);
export const serverTimestamp = ɵzoneWrap(_serverTimestamp, true);
export const setDoc = ɵzoneWrap(_setDoc, true);
export const setIndexConfiguration = ɵzoneWrap(_setIndexConfiguration, true);
export const setLogLevel = ɵzoneWrap(_setLogLevel, true);
export const snapshotEqual = ɵzoneWrap(_snapshotEqual, true);
export const startAfter = ɵzoneWrap(_startAfter, true);
export const startAt = ɵzoneWrap(_startAt, true);
export const sum = ɵzoneWrap(_sum, true);
export const terminate = ɵzoneWrap(_terminate, true);
export const updateDoc = ɵzoneWrap(_updateDoc, true);
export const vector = ɵzoneWrap(_vector, true);
export const waitForPendingWrites = ɵzoneWrap(_waitForPendingWrites, true);
export const where = ɵzoneWrap(_where, true);
export const writeBatch = ɵzoneWrap(_writeBatch, true);

Should AngularFire take a more granular approach and throw warnings only on async functions such as docData to avoid extraneous warnings?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions