react-native-firebase icon indicating copy to clipboard operation
react-native-firebase copied to clipboard

[πŸ›] πŸ”₯Firestore Typescript types are not working anymore with 22.3.0

Open dhenneke opened this issue 5 months ago β€’ 16 comments

Issue

We noticed that our TypeScript setup doesn't work anymore with the latest 22.3.0. This is most likely caused by https://github.com/invertase/react-native-firebase/pull/8378.

One cause could be that the following type points to Query<AppModelType, DbModelType>:

https://github.com/invertase/react-native-firebase/blob/7eaaf185aab15c7e4fc3c218af9be609fe7e0030/packages/firestore/lib/modular/query.d.ts#L103-L107

But that type (and similar ones in this file) was not updated and doesn't support the second parameter:

https://github.com/invertase/react-native-firebase/blob/7eaaf185aab15c7e4fc3c218af9be609fe7e0030/packages/firestore/lib/index.d.ts#L980


For reference this is how this is typed in firebase-js-sdk:

https://github.com/firebase/firebase-js-sdk/blob/d91169f061bf1dcbfe78a8c8a7f739677608fcb7/packages/firestore/src/lite-api/query.ts#L136-L140

Using this type:

https://github.com/firebase/firebase-js-sdk/blob/d91169f061bf1dcbfe78a8c8a7f739677608fcb7/packages/firestore/src/lite-api/reference.ts#L118-L121


Reproducible example with type errors

rnfirebase-example.ts:

  • βœ…: works as expected
  • πŸ€”: The custom type disappeared for some reason.
  • 🚨: why is this suddenly any?
import {
    collection,
    doc,
    FirebaseFirestoreTypes,
    getDoc,
    getDocs,
    getFirestore,
    limit,
    query,
} from '@react-native-firebase/firestore'

type UserType = { id: string }

const firestore = getFirestore()

/// OLD API ///

{
    // GET SINGLE DOCUMENT //

    // 22.2.1    `FirebaseFirestoreTypes.DocumentReference<UserType>` βœ…
    // 22.3.0    `FirebaseFirestoreTypes.DocumentReference<UserType>` βœ…
    // Expected: `FirebaseFirestoreTypes.DocumentReference<UserType>`
    const userReferenceWithT = doc(
        firestore,
        'users/123',
        // this cast worked in 22.2.1, should actually be `doc<UserType>`
    ) as FirebaseFirestoreTypes.DocumentReference<UserType>
    // 22.2.1    `FirebaseFirestoreTypes.DocumentSnapshot<UserType>` βœ…
    // 22.3.0    `FirebaseFirestoreTypes.DocumentSnapshot<UserType>` βœ…
    // Expected: `FirebaseFirestoreTypes.DocumentSnapshot<UserType>`
    const userSnapshotWithT = await getDoc(userReferenceWithT)
    // 22.2.1    `UserType | undefined` βœ…
    // 22.3.0    `UserType | undefined` βœ…
    // Expected: `UserType | undefined`
    const _userWithT = userSnapshotWithT.data()

    // GET MULTIPLE DOCUMENTS FROM COLLECTION //

    // 22.2.1:   `FirebaseFirestoreTypes.Query<UserType>` βœ…
    // 22.3.0:   `FirebaseFirestoreTypes.Query<UserType>` βœ…
    // Expected: `FirebaseFirestoreTypes.Query<UserType>`
    const usersQueryReferenceWithT = query(
        // this cast worked in 22.2.1, should actually be `query<UserType>`
        collection(firestore, 'users') as FirebaseFirestoreTypes.CollectionReference<UserType>,
        limit(10),
    )
    // 22.2.1    `FirebaseFirestoreTypes.QuerySnapshot<UserType>` βœ…
    // 22.3.0    `any` 🚨
    // Expected: `FirebaseFirestoreTypes.QuerySnapshot<UserType, UserType>`
    const usersSnapshotWithT = await getDocs(usersQueryReferenceWithT)
    // 22.2.1: `UserType[]` βœ…
    // 22.3.0 `any` 🚨
    // Expected: `UserType[]`
    const _usersWithT = usersSnapshotWithT.docs.map((d) => d.data())
}

/// UPDATED API ///

{
    // GET SINGLE DOCUMENT //

    // 22.2.1:   ... didn't exist ...
    // 22.3.0    `any` 🚨
    // Expected: `FirebaseFirestoreTypes.DocumentReference<UserType, UserType>`
    const userReferenceWithT = doc<UserType, UserType>(firestore, 'users/123')
    // 22.2.1:   ... didn't exist ...
    // 22.3.0    `FirebaseFirestoreTypes.DocumentSnapshot<unknown>` πŸ€”
    // Expected: `FirebaseFirestoreTypes.DocumentSnapshot<UserType, UserType>`
    const userSnapshotWithT = await getDoc(userReferenceWithT)
    // 22.2.1:   ... didn't exist ...
    // 22.3.0    `unknown` πŸ€”
    // Expected: `UserType | undefined`
    const _userWithT = userSnapshotWithT.data()

    // GET MULTIPLE DOCUMENTS FROM COLLECTION //

    // 22.2.1:   ... didn't exist ...
    // 22.3.0:   `any` 🚨
    // Expected: `FirebaseFirestoreTypes.Query<UserType, UserType>`
    const usersQueryReferenceWithT = query<UserType, UserType>(
        collection(firestore, 'users'),
        limit(10), // This isn't valid for some reason 🚨
    )
    // 22.2.1:   ... didn't exist ...
    // 22.3.0    `any` 🚨
    // Expected: `FirebaseFirestoreTypes.QuerySnapshot<UserType, UserType>`
    const usersSnapshotWithT = await getDocs(usersQueryReferenceWithT)
    // 22.2.1:   ... didn't exist ...
    // 22.3.0 `any` 🚨
    // Expected: `UserType[]`
    const _usersWithT = usersSnapshotWithT.docs.map((d) => d.data())
}

dhenneke avatar Jul 14 '25 17:07 dhenneke

Hi there, I don't seem to be able to reproduce this, could you provide a repo I could clone and investigate further? Could you also show any log output you get?

MichaelVerdon avatar Jul 16 '25 09:07 MichaelVerdon

I pushed my example from above into this repo: https://github.com/dhenneke/react-native-firebase-issues-8611

Run npm run typecheck and/or look at it in an IDE. The comments show which types we expect and which types are returned.

dhenneke avatar Jul 16 '25 11:07 dhenneke

Hi there, I was able to get it working by importing FirebaseFirestoreTypes and casting using that. e.t.c This should expose the types and get rid of the linter error.

const usersQueryReferenceWithT = query(
              collection(firestore, "users") as FirebaseFirestoreTypes.CollectionReference<UserType>,
              limit(10)
            );

MichaelVerdon avatar Jul 21 '25 11:07 MichaelVerdon

For the limit, yes. But passing that reference to getDocs will still result in any instead of a properly typed snapshot. And we don't really want to do const usersSnapshotWithT = await getDocs(usersQueryReferenceWithT) as FirebaseFirestoreTypes.QuerySnapshot<UserType> because we loose type safety for the queries in our code.

dhenneke avatar Jul 22 '25 09:07 dhenneke

Same for me. Since updating I have many Type Issues where the modular functions just return any.

Version 22.3.0 or 22.4.0:

Image

Version 22.1.0:

Image

I am using Typescript Version 5.8.3

There are many others:

Image Image

lautenschlager-dev avatar Jul 28 '25 08:07 lautenschlager-dev

For the limit, yes. But passing that reference to getDocs will still result in any instead of a properly typed snapshot. And we don't really want to do const usersSnapshotWithT = await getDocs(usersQueryReferenceWithT) as FirebaseFirestoreTypes.QuerySnapshot<UserType> because we loose type safety for the queries in our code.

We do have full plans to fully migrate this repo to typescript for the type safety it offers.

MichaelVerdon avatar Aug 04 '25 13:08 MichaelVerdon

I'm also seeing a bunch of new Typescript errors that were not happening with the same code in previous v22 of react-native-firebase. I'm currently running react-native-firebase v22.4.0 and typescript: 5.8.3

Looks like this:

Argument of type 'QueryFieldFilterConstraint' is not assignable to parameter of type 'QueryConstraint'.
  Property '_apply' is missing in type 'QueryFieldFilterConstraint' but required in type 'QueryConstraint'.ts(2345)
query.d.ts(51, 3): '_apply' is declared here.

pweisensee avatar Aug 05 '25 06:08 pweisensee

Hello πŸ‘‹, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

github-actions[bot] avatar Sep 02 '25 07:09 github-actions[bot]

I do believe this is still an issue as of a week ago

pweisensee avatar Sep 03 '25 05:09 pweisensee

This is a real blocker for typescript projects, I can't believe it was released without strong typing but even the firebase web sdk seems to be an after thought and their documentation is all .js and no TS from what I can see.

And even with this v22 release all the docs still describe the namespace api and the only modular examples are on the migration page.

At least with the web version there is a .withConverter() method which handles the conversion of DocumentData to a custom type/interface - seems the react-native-firebase is also missing that functionality.

The problem with casting as suggested above is that it is really hard to come back to and do the right way even if these types get fixed in a future release, not to mention the risks to runtime execution and no compile time safety.

ChromeQ avatar Sep 10 '25 00:09 ChromeQ

I noticed that CollectionReference is declared with only one type parameter, but is frequently passed two. I don't think tsc even passes on index.d.ts...?

macksal avatar Sep 11 '25 14:09 macksal

Created a PR #8698 to fix the types.

ycmjason avatar Sep 16 '25 08:09 ycmjason

I'm having problems with modular API types in v23.4.0 as well. Namespaced API types seem to work fine.

jonjamz avatar Oct 02 '25 21:10 jonjamz

Created a PR #8698 to fix the types.

There are still functions retuning any even on the newest version.

Image

lautenschlager-dev avatar Oct 26 '25 10:10 lautenschlager-dev

Hello πŸ‘‹, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

github-actions[bot] avatar Nov 23 '25 10:11 github-actions[bot]

Not stale

ChromeQ avatar Nov 23 '25 10:11 ChromeQ