Skip to content

collection() missing type arguments #3081

Closed

Description

@imjoshnewton

There are no exported functions for the collection function that allow a type to be specified. I see reference to collection() in the docs and in the upgrade information (screenshot below) but it isn't working in my project. If I try to add a type to get a typed collection reference, I get the error: Expected 0 type arguments, but got 1.

Version info

Angular: 13.0.3

Firebase: 9.0.0

AngularFire: 7.2

Other (e.g. Ionic/Cordova, Node, browser, operating system): MacOs Montery

How to reproduce these conditions

Steps to set up and reproduce

Attempt to create a collection reference with a custom type

Sample data and security rules

The data isn't important.

Debug output

Error in VS Code:
image

AngularFire Upgrade Docs:
image

Expected behavior

There should be a version of the collection function that takes a type. There are version of other functions that take a type and even expect a typed CollectionReference.

Actual behavior

No function exists that takes a type.

Activity

  1. changed the title [-]collection() missing missing types[/-] [+]collection() missing type arguments[/+] on Dec 3, 2021
  2. juane1000 commented on Dec 14, 2021

    @juane1000

    Just upgraded and immediately noticed this...

  3. nutangwari commented on Dec 23, 2021

    @nutangwari

    +1

    any solution or workaround for above issue ?

  4. Methodician commented on Jan 6, 2022

    @Methodician

    I'm rolling with a work-around but it doesn't make me happy. Presumably I'll have to do another refactor when they fix this.

    customerCol = collection(firestore, 'customers') as CollectionReference<CustomerI>;

    I spent like an hour wrestling with this thinking I misunderstood something because when I Google about the problem, nothing comes up. Not even this issue. Surely more folks have upgraded than just us three... I hope this gets worked out soon!

    Still gotta thank the team and the community for this great revamp.

  5. imjoshnewton commented on Jul 22, 2022

    @imjoshnewton
    Author

    I'm rolling with a work-around but it doesn't make me happy. Presumably I'll have to do another refactor when they fix this.

    customerCol = collection(firestore, 'customers') as CollectionReference<CustomerI>;

    I spent like an hour wrestling with this thinking I misunderstood something because when I Google about the problem, nothing comes up. Not even this issue. Surely more folks have upgraded than just us three... I hope this gets worked out soon!

    Still gotta thank the team and the community for this great revamp.

    I am doing something similar but slightly different. When I need to return an observable to something like collectionData, I have that behind a function in a service and add an 'as' statement to the return.

    return collectionData(q, { idField: 'id'}) as Observable<Team[]>

    This way I can still get a typed object in the code that consumes the observable.

  6. kisamoto commented on Mar 20, 2023

    @kisamoto

    I have a service that I use in my components for interacting with Firebase. I've added the following helper methods to deal with V9:

      _collection<T>(colPath: string) {
        // Dirty helper function to get a typed CollectionReference
        // Can change this once 3081 is fixed
        // https://github.com/angular/angularfire/issues/3081
        return collection(this.afs, colPath) as CollectionReference<T>;
      }
    
      _listDocs<T>(colPath: string) {
        return getDocs(this._collection<T>(colPath));
      }
    
      _doc<T>(docPath: string) {
        return doc(this.afs, docPath) as DocumentReference<T>;
      }
    
      _getDoc<T>(docPath: string) {
        return getDoc<T>(this._doc(docPath));
      }
    
      _addDoc<T>(colPath: string, data: T): Observable<DocumentReference<T>> {
        const col = this._collection<T>(colPath);
        return from(addDoc<T>(col, data));
      }
    
      _addReadDoc<T>(colPath: string, data: T): Observable<T> {
        // Helper function that not only adds a document but then instantly retrieves it
        return this._addDoc(colPath, data).pipe(
          switchMap((ref) => from(getDoc(ref))
            .pipe(
              map(doc => doc.data()),
              filterNullish(),
            ),
          ),
        );
      }

    And the helper function that removes undefined:

    // Helper function to filter out nullish values
    // https://stackoverflow.com/a/62971842/1401034
    function filterNullish<T>(): UnaryFunction<Observable<T | null | undefined>, Observable<T>> {
      return pipe(
        filter(x => x != null) as OperatorFunction<T | null |  undefined, T>
      );
    }

    Then I can use them elsewhere in my service with my models:

      getOrganization(pathToDoc: string){
        return this._getDoc(pathToDoc);
      }
      
      createOrganization(organization: Organization): Observable<Organization> {
        return this._addReadDoc('organizations', organization);
      }

    It would be useful if this was better supported but for now this seems to work

  7. armando-navarro commented on Nov 5, 2026

    @armando-navarro
    Collaborator

    Thanks for the report, and to everyone who added a workaround here. Sorry this issue sat for years.

    The signature is the Firebase SDK's, not AngularFire's. collection(firestore, path) returns CollectionReference<DocumentData> in firebase/firestore itself, and the SDK's way to type a reference is withConverter().

    AngularFire re-exports those functions unchanged, so adding a collection<T>() overload here would make AngularFire's types disagree with Firebase's (jamesdaniels said the same on #2931 in 2021). A converter also gives you something the type argument never could: a place where every document is checked on its way in.

    What I did change is the docs, which were showing the call that fails. #3838 replaces collectionData<Item>(collection(...)) in the README and the quickstart with a converter-typed reference, and adds a "Typed reads" section to docs/firestore.md that explains the two shortcuts that do not work and shows the converter pattern. The short version:

    const itemConverter: FirestoreDataConverter<Item> = {
      toFirestore: item => item,
      fromFirestore: (snapshot, options) => {
        const data = snapshot.data(options);
        return { name: typeof data['name'] === 'string' ? data['name'] : '' };
      },
    };
    
    const items = collection(firestore, 'items').withConverter(itemConverter);
    items$ = collectionData(items); // Observable<Item[]>, no cast

    If there is a case where the converter does not work for you, let me know.

  8. added
    comp: firestoreCloud Firestore (src/firestore).
    comp: typingsTypeScript type correctness across the public API.
    type: featureNew capability or enhancement.
    on Nov 5, 2026
  9. added this to the 22.0.0-rc.1 milestone on Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    comp: firestoreCloud Firestore (src/firestore).comp: typingsTypeScript type correctness across the public API.type: featureNew capability or enhancement.version: legacy (v7-v16)Targets the older modular API (roughly v7-v16).

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions