Skip to content

refactor(installations)!: migrate to TypeScript#9002

Merged
mikehardy merged 1 commit into
mainfrom
installations-typescript
May 15, 2026
Merged

refactor(installations)!: migrate to TypeScript#9002
mikehardy merged 1 commit into
mainfrom
installations-typescript

Conversation

@russellwheatley
Copy link
Copy Markdown
Member

@russellwheatley russellwheatley commented Apr 30, 2026

Updated to main and re-pushed to verify things still work since we're not using a merge queue here

release notes will come from the commit, so here's the draft of the commit message pulled from the description:


BREAKING CHANGE: installations modular types now match firebase-js-sdk

Please see https://rnfirebase.io/migrating-to-v25 for help migrating if needed.

react-native-firebase has a goal to be a drop-in replacement for firebase-js-sdk, with native extensions and performance. It has always worked that way at the javascript level but the typescript types have been divergent.

We are fixing that as we refactor to typescript. Please bear with us as we get closer to our goal of react-native-firebase matching firebase-js-sdk both in functionality where possible, but also in exact typescript typing.

Specifics for Installations:

  • changed modular getInstallations() to return the firebase-js-sdk-style Installations type, which only exposes app; TypeScript consumers should use the modular helpers getId(installations), getToken(installations), and deleteInstallations(installations) instead of calling .getId(), .getToken(), or .delete() on the returned instance.
  • changed modular deleteInstallations(installations) so the installations argument is required in the TypeScript surface, matching firebase-js-sdk. Code that previously relied on the old optional typing should pass getInstallations() explicitly.
  • preserved the namespaced API surface: installations(), firebase.installations(), firebase.app().installations(), and FirebaseInstallationsTypes.Module remain available for compatibility, with deprecation annotations added.
  • added explicit modular public types including Installations, IdChangeCallbackFn, and IdChangeUnsubscribeFn.

Related issues

Release Summary

Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
    • Yes
  • My change supports the following platforms;
    • Android
    • iOS
    • Other (macOS, web)
  • My change includes tests;
    • e2e tests added or updated in packages/\*\*/e2e
    • jest tests added or updated in packages/\*\*/__tests__
  • I have updated TypeScript types that are affected by my change.
  • This is a breaking change;
    • Yes
    • No

Test Plan


Think react-native-firebase is great? Please consider supporting the project with any of the below:

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request completes the migration of the installations package to TypeScript. It updates the build configuration to use modern standards, improves type definitions, and refactors the internal module structure to align with the project's modular API strategy while ensuring existing consumers remain supported.

Highlights

  • TypeScript Migration: Migrated the installations package to TypeScript, improving type safety and developer experience.
  • Build System Update: Integrated react-native-builder-bob for improved build processes and package exports.
  • API Refactoring: Refactored the internal structure to better support modular and namespaced APIs, while maintaining backward compatibility.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request transitions the Firebase Installations package to a modular architecture, adding modular API functions and updating the build process with react-native-builder-bob. It also includes comprehensive type definitions and consistency check configurations. Feedback focuses on simplifying the implementation of getInstallations and getToken by utilizing optional chaining and boolean conversion to eliminate redundant conditional logic.

Comment thread packages/installations/lib/modular.ts
Comment thread packages/installations/lib/namespaced.ts
@russellwheatley russellwheatley changed the title refactor(installations)!: migrate to TypeScript refactor(installations): migrate to TypeScript May 1, 2026
@russellwheatley russellwheatley changed the title refactor(installations): migrate to TypeScript refactor(installations)!: migrate to TypeScript May 1, 2026
@russellwheatley russellwheatley marked this pull request as ready for review May 1, 2026 15:57
Copy link
Copy Markdown
Collaborator

@mikehardy mikehardy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no reason to sit on this one (any more than it has) - looks great

@mikehardy mikehardy added the Workflow: Pending Merge Waiting on CI or similar label May 14, 2026
BREAKING CHANGE: installations modular types now match firebase-js-sdk

Please see https://rnfirebase.io/migrating-to-v25 for help migrating if needed.

react-native-firebase has a goal to be a drop-in replacement for firebase-js-sdk, with native extensions and performance. It has always worked that way at the javascript level but the typescript types have been divergent.

We are fixing that as we refactor to typescript. Please bear with us as we get closer to our goal of react-native-firebase matching firebase-js-sdk both in functionality where possible, but also in exact typescript typing.

Specifics for Installations:

changed modular getInstallations() to return the firebase-js-sdk-style Installations type, which only exposes app; TypeScript consumers should use the modular helpers getId(installations), getToken(installations), and deleteInstallations(installations) instead of calling .getId(), .getToken(), or .delete() on the returned instance.
changed modular deleteInstallations(installations) so the installations argument is required in the TypeScript surface, matching firebase-js-sdk. Code that previously relied on the old optional typing should pass getInstallations() explicitly.
preserved the namespaced API surface: installations(), firebase.installations(), firebase.app().installations(), and FirebaseInstallationsTypes.Module remain available for compatibility, with deprecation annotations added.
added explicit modular public types including Installations, IdChangeCallbackFn, and IdChangeUnsubscribeFn.
@mikehardy mikehardy force-pushed the installations-typescript branch from a323b02 to 7deaaa7 Compare May 15, 2026 03:19
@mikehardy
Copy link
Copy Markdown
Collaborator

That's a crash I've never seen before - but release passed - I don't think this is a bug in the work here, though maybe just maybe we have an issue in our underlying obj-c code

Saving for posterity but green-lighting the PR

        modular
          ✔ should throw if updateFunction is not a Promise
          ✔ should return an instance of FirestoreTransaction
          ✔ should resolve with user value
          ✔ should reject with user Error
          ✔ should reject a native error
          transaction.get()
            ✔ should throw if not providing a document reference
            ✔ should get a document and return a DocumentSnapshot
          transaction.delete()
            ✔ should throw if not providing a document reference
            ✔ should delete documents
          transaction.update()
            ✔ should throw if not providing a document reference
            ✔ should throw if update args are invalid
            ✔ should update documents
          transaction.set()
            ✔ should throw if not providing a document reference
            ✔ should throw if set data is invalid
            ✔ should throw if set options are invalid
            ✔ should set data
            ✔ should set data with merge
            ✔ should set data with merge fields
03:43:18.810 detox[81290] E ws-server connection :50166<->:50174
[🟨] Jet client disconnected - for no particular reason (code = 1006).
[🧹] Stopped the server
[🟥] Exiting after an abnormal disconnect.
[🪝] Running after hook...
03:43:18.822 detox[81380] i ws-client 
  error: The app has crashed, see the details below:
  
  NSInternalInconsistencyException
  FIRESTORE INTERNAL ASSERTION FAILED: A transaction object cannot be used after its update callback has been invoked. (expected !committed_)
  (
  	0   CoreFoundation                      0x00000001804f71c4 __exceptionPreprocess + 160
  	1   libobjc.A.dylib                     0x000000018009c094 objc_exception_throw + 72
  	2   Foundation                          0x000000018104ec88 -[NSMutableDictionary(NSMutableDictionary) classForCoder] + 0
  	3   testing                             0x0000000104c96328 firebase::firestore::util::ObjcThrowHandler(firebase::firestore::util::ExceptionType, char const*, char const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&) + 292
  	4   testing                             0x0000000104c95d3c firebase::firestore::util::Throw(firebase::firestore::util::ExceptionType, char const*, char const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&) + 20
  	5   testing                             0x0000000104d0bba0 firebase::firestore::util::internal::FailAssertion(char const*, char const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, char const*) + 0
  	6   testing                             0x0000000104d0bc40 firebase::firestore::util::internal::FailAssertion(char const*, char const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, char const*) + 160
  	7   testing                             0x0000000104dd0908 firebase::firestore::core::Transaction::EnsureCommitNotCalled() + 104
  	8   testing                             0x0000000104dd0580 firebase::firestore::core::Transaction::Lookup(std::__1::vector<firebase::firestore::model::DocumentKey, std::__1::allocator<firebase::firestore::model::DocumentKey>> const&, std::__1::function<void (firebase::firestore::util::StatusOr<std::__1::vector<firebase::firestore::model::Document, std::__1::allocator<firebase::firestore::model::Document>>> const&)>&&) + 56
  	9   testing                             0x0000000104cf693c -[FIRTransaction getDocument:completion:] + 256
  	10  testing                             0x0000000104cf6b10 -[FIRTransaction getDocument:error:] + 200
  	11  testing                             0x0000000105497e30 -[RNFBFirestoreTransactionModule transactionGetDocument::::::] + 620
  	12  CoreFoundation                      0x00000001804fdba0 __invoking___ + 144
  	13  CoreFoundation                      0x00000001804fad44 -[NSInvocation invoke] + 276
  	14  CoreFoundation                      0x00000001804fafc8 -[NSInvocation invokeWithTarget:] + 60
  	15  testing                             0x00000001058c2490 invocation function for block in facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*) + 196
  	16  testing                             0x00000001058d19cc facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1::operator()() const + 116
  	17  testing                             0x00000001058d194c decltype(std::declval<facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1&>()()) std::__1::__invoke[abi:de200100]<facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1&>(facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1&) + 24
  	18  testing                             0x00000001058d1928 void std::__1::__invoke_void_return_wrapper<void, true>::__call[abi:de200100]<facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1&>(facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1&) + 24
  	19  testing                             0x00000001058d1904 void std::__1::__invoke_r[abi:de200100]<void, facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1&>(facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1&) + 24
  	20  testing                             0x00000001058d18e0 std::__1::__function::__alloc_func<facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1, std::__1::allocator<facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1>, void ()>::operator()[abi:de200100]() + 24
  	21  testing                             0x00000001058d100c std::__1::__function::__func<facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1, std::__1::allocator<facebook::react::ObjCTurboModule::performMethodInvocation(facebook::jsi::Runtime&, bool, char const*, NSInvocation*, NSMutableArray*)::$_1>, void ()>::operator()() + 28
  	22  testing                             0x0000000105537fd4 std::__1::__function::__value_func<void ()>::operator()[abi:de200100]() const + 60
  	23  testing                             0x0000000105537efc std::__1::function<void ()>::operator()() const + 24
  	24  testing                             0x00000001058df4b4 invocation function for block in (anonymous namespace)::ModuleNativeMethodCallInvoker::invokeAsync(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, std::__1::function<void ()>&&) + 44
  	25  DetoxSync                           0x000000010977079c ____detox_sync_dispatch_wrapper_block_invoke + 44
  	26  libdispatch.dylib                   0x00000001801c07a8 _dispatch_call_block_and_release + 24
  	27  libdispatch.dylib                   0x00000001801db4b0 _dispatch_client_callout + 12
  	28  libdispatch.dylib                   0x00000001801c9c28 _dispatch_lane_serial_drain + 984
  	29  libdispatch.dylib                   0x00000001801ca6e8 _dispatch_lane_invoke + 396
  	30  libdispatch.dylib                   0x00000001801d5534 _dispatch_root_queue_drain_deferred_wlh + 288
  	31  libdispatch.dylib                   0x00000001801d4c74 _dispatch_workloop_worker_thread + 692
  	32  libsystem_pthread.dylib             0x0000000109266b88 _pthread_wqthread + 288
  	33  libsystem_pthread.dylib             0x000000010926598c start_wqthread + 8
  )

@mikehardy mikehardy removed the Workflow: Pending Merge Waiting on CI or similar label May 15, 2026
@mikehardy mikehardy merged commit 739a4ca into main May 15, 2026
19 of 20 checks passed
@mikehardy mikehardy deleted the installations-typescript branch May 15, 2026 03:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants