Skip to content

Commit ab1cc1c

Browse files
committed
docs: update v26 migration parity notes
1 parent e589ab4 commit ab1cc1c

2 files changed

Lines changed: 44 additions & 19 deletions

File tree

docs/migrating-to-v26.mdx

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,20 @@ Native builds fail early with explicit guards:
8383

8484
When migrating from firebase-js-sdk web examples, watch for these high-impact runtime divergences:
8585

86-
| Area | firebase-js-sdk (web) | React Native Firebase |
87-
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
88-
| **Auth** | Browser persistence, redirects, reCAPTCHA, `revokeAccessToken`, `useDeviceLanguage`, `linkWithPhoneNumber` / `reauthenticateWithPhoneNumber` | Native iOS/Android SDKs manage persistence. Several web-only helpers **throw synchronously** on React Native (`setPersistence`, `getRedirectResult`, `revokeAccessToken`, `useDeviceLanguage`, `linkWithPhoneNumber`, `reauthenticateWithPhoneNumber`). Use native provider flows instead. |
89-
| **Analytics** | Cross-platform modular API | On-device conversion measurement helpers (`initiateOnDeviceConversionMeasurement*`) are **iOS only**; on Android and web the JS layer resolves without calling native (no-op). `logTransaction` (verified iOS in-app purchase events) is **iOS only** and **rejects** on other platforms. |
90-
| **Realtime Database** | `goOnline` / `goOffline` are synchronous; web transport toggles | `goOnline` / `goOffline` are **synchronous** through TurboModules, matching firebase-js-sdk. `getServerTime`, `setPersistenceEnabled`, and `setPersistenceCacheSizeBytes` are RN-specific. `forceLongPolling` / `forceWebSockets` **throw** — transport is native-controlled. |
91-
| **Phone Number Verification** | N/A (Android SDK only) | **Android only** — all entry points throw on iOS and Web. |
92-
| **Cloud Storage** | `uploadBytes` / `uploadString` from JS blobs | `putFile` and `writeToFile` are **native-only** file-path APIs with no firebase-js-sdk equivalent. Retry-time setters are modular functions on RN, not instance properties. |
93-
| **Cloud Messaging** | Web push / service-worker surface | FCM token lifecycle, permissions, background handlers, and **APNs token APIs are iOS only**. Event delivery still uses the legacy native event proxy during the TurboModule migration; behavior matches pre-v26 releases but will change when Codegen events land in a future release. |
94-
| **Remote Config** | `reset()` clears server and local state | `reset()` is **Android only** — iOS does not clear activated, fetched, or default Remote Config values. `setDefaultsFromResource` loads from native resource files (`.plist` / XML). |
95-
| **Performance** | `initializePerformance` returns synchronously; trace `start`/`stop` are sync | `initializePerformance` is **synchronous** on RN (applies settings to the native instance). Trace, HTTP metric, and screen trace `start`/`stop` are **synchronous** through TurboModules, matching firebase-js-sdk. |
96-
| **Firestore** | IndexedDB persistence, `memoryLocalCache`, `persistentLocalCache` | Local cache factories and IndexedDB APIs are **web only**. Persistence is controlled by the native Firestore SDK. `initializeFirestore` returns **`Firestore` synchronously** (settings apply in the background). |
97-
| **App Check** | reCAPTCHA version 3 / Enterprise web providers | Use `ReactNativeFirebaseAppCheckProvider` for Device Check, App Attest, Play Integrity, etc. Web reCAPTCHA provider classes have **no RN equivalent**. |
98-
| **RN-native-only modules** | No web SDK | `crashlytics`, `in-app-messaging`, `app-distribution`, and `ml` are **React Native only** — no firebase-js-sdk modular surface. |
86+
{/* prettier-ignore */}
87+
| Area | firebase-js-sdk (web) | React Native Firebase |
88+
| --- | --- | --- |
89+
| **Auth** | Browser persistence, redirects, reCAPTCHA, `revokeAccessToken`, `useDeviceLanguage`, `linkWithPhoneNumber` / `reauthenticateWithPhoneNumber` | Native iOS/Android SDKs manage persistence. Several web-only helpers **throw synchronously** on React Native (`setPersistence`, `getRedirectResult`, `revokeAccessToken`, `useDeviceLanguage`, `linkWithPhoneNumber`, `reauthenticateWithPhoneNumber`). Use native provider flows instead. |
90+
| **Analytics** | Cross-platform modular API | On-device conversion measurement helpers (`initiateOnDeviceConversionMeasurement*`) are **iOS only**; on Android and web the JS layer resolves without calling native (no-op). `logTransaction` (verified iOS in-app purchase events) is **iOS only** and **rejects** on other platforms. |
91+
| **Realtime Database** | `goOnline` / `goOffline` are synchronous; web transport toggles | `goOnline` / `goOffline` are **synchronous** through TurboModules, matching firebase-js-sdk. `getServerTime`, `setPersistenceEnabled`, and `setPersistenceCacheSizeBytes` are RN-specific. `forceLongPolling` / `forceWebSockets` **throw** — transport is native-controlled. |
92+
| **Phone Number Verification** | N/A (Android SDK only) | **Android only** — all entry points throw on iOS and Web. |
93+
| **Cloud Storage** | `uploadBytes` / `uploadString` from JS blobs; upload task controls return sync `boolean` | `putFile` and `writeToFile` are **native-only** file-path APIs. `UploadTask.pause()` / `.resume()` / `.cancel()` also return sync `boolean` values through native TurboModules. |
94+
| **Cloud Messaging** | Web push / service-worker surface | FCM token lifecycle, permissions, background handlers, and **APNs token APIs are iOS only**. Event delivery still uses the legacy native event proxy during the TurboModule migration; behavior matches pre-v26 releases but will change when Codegen events land in a future release. |
95+
| **Remote Config** | `reset()` clears server and local state | `reset()` is **Android only** — iOS does not clear activated, fetched, or default Remote Config values. `setDefaultsFromResource` loads from native resource files (`.plist` / XML). |
96+
| **Performance** | `initializePerformance` returns synchronously; trace `start`/`stop` are sync | `initializePerformance` is **synchronous** on RN (applies settings to the native instance). Trace, HTTP metric, and screen trace `start`/`stop` are **synchronous** through TurboModules, matching firebase-js-sdk. |
97+
| **Firestore** | IndexedDB persistence, `memoryLocalCache`, `persistentLocalCache`, FieldValue `maximum()` / `minimum()` sentinels | Local cache factories and IndexedDB APIs are **web only**. Persistence is controlled by the native Firestore SDK. `initializeFirestore` returns **`Firestore` synchronously**. FieldValue `maximum()` / `minimum()` are not exported yet because iOS SDK 12.15.0 lacks matching native factories. |
98+
| **App Check** | reCAPTCHA version 3 / Enterprise web providers | Use `ReactNativeFirebaseAppCheckProvider` for Device Check, App Attest, Play Integrity, etc. Web reCAPTCHA provider classes have **no RN equivalent**. |
99+
| **RN-native-only modules** | No web SDK | `crashlytics`, `in-app-messaging`, `app-distribution`, and `ml` are **React Native only** — no firebase-js-sdk modular surface. |
99100

100101
Per-package notes also appear in each module's [usage](/) page under **Platform support**.
101102

@@ -107,6 +108,7 @@ v26 aligns React Native Firebase modular types and several runtime signatures wi
107108

108109
### Phase S — TurboModule sync conversion (new-architecture)
109110

111+
{/* prettier-ignore */}
110112
| Method | Before (pre-v26 / legacy bridge) | After (v26) | Notes |
111113
| ------ | -------------------------------- | ----------- | ----- |
112114
| `registerVersion(library, version, variant?)` | `Promise<void>` (web) | `void` — throws on RN | Web-only on RN; remove `await` if copied from web samples |
@@ -117,9 +119,11 @@ v26 aligns React Native Firebase modular types and several runtime signatures wi
117119
| `ScreenTrace.start()` / `.stop()` | `Promise<null>` | `void` | Same as traces |
118120
| `startScreenTrace(performance, screenName)` | `Promise<ScreenTrace>` | `ScreenTrace` | Remove `await` |
119121
| `goOnline(db)` / `goOffline(db)` | `Promise<void>` | `void` | Remove `await` |
122+
| `UploadTask.pause()` / `.resume()` / `.cancel()` | `Promise<boolean>` | `boolean` | Remove `await`; use the returned boolean directly |
120123

121124
### Compare-types Phase A — type parity (no runtime sync change unless noted)
122125

126+
{/* prettier-ignore */}
123127
| Export / method | Before | After | Notes |
124128
| --------------- | ------ | ----- | ----- |
125129
| `onSnapshotsInSync(firestore, observer)` | `next?: () => void`; `error?: Error` | `next?: (value: void) => void`; `error?: FirestoreError` | Callback overload `onSnapshotsInSync(firestore, () => {})` unchanged |
@@ -132,6 +136,7 @@ v26 aligns React Native Firebase modular types and several runtime signatures wi
132136

133137
### Compare-types Phase B — sync façades (native work may still be async)
134138

139+
{/* prettier-ignore */}
135140
| Method | Before | After | Notes |
136141
| ------ | ------ | ----- | ----- |
137142
| `logEvent(analytics, …)` | `Promise<void>` | `void` | Fire-and-forget; remove `await` / `.then()` |
@@ -141,8 +146,19 @@ v26 aligns React Native Firebase modular types and several runtime signatures wi
141146
| `aggregateFieldEqual()` | Not exported | Exported | Aggregate query helper |
142147
| `LastFetchStatus` literals ||| **Unchanged** — native still uses `no_fetch_yet` / `throttled` (documented drift) |
143148

149+
### Compare-types Phase C — Firestore parity additions
150+
151+
{/* prettier-ignore */}
152+
| Export / method | Before | After | Notes |
153+
| --------------- | ------ | ----- | ----- |
154+
| `TransactionOptions` | Not exported | Exported | Type for transaction retry options |
155+
| `runTransaction(firestore, updateFunction, options?)` | No options argument | Accepts `options?: TransactionOptions` | Supports `{ maxAttempts?: number }` on native iOS and Android |
156+
| `aggregateQuerySnapshotEqual()` | Not exported | Exported | Aggregate query snapshot equality helper, alongside `aggregateFieldEqual()` |
157+
| `maximum(n)` / `minimum(n)` FieldValue sentinels | Exported by firebase-js-sdk 12.15.0 | Not exported by RNFB yet | Android SDK 34.15.0 has native factories, but iOS Firebase Firestore SDK 12.15.0 does not; RNFB waits for cross-platform parity |
158+
144159
### Observer and Promise pitfalls
145160

161+
{/* prettier-ignore */}
146162
| Pitfall | Symptom | Fix |
147163
| ------- | ------- | --- |
148164
| `.then()` on sync API | `TypeError: … .then is not a function` | Use direct call: `logEvent(…)` not `logEvent(…).then(…)` |
@@ -613,6 +629,11 @@ The namespaced API for `@react-native-firebase/storage` has been **removed**. Th
613629
| `storage().ref()` | `ref(storage, path?)` |
614630
| `storageRef.put()` | `uploadBytesResumable(storageRef, data, metadata?)` |
615631

632+
## Signature changes
633+
634+
- `UploadTask.pause()`, `UploadTask.resume()`, and `UploadTask.cancel()` now return `boolean` synchronously (previously `Promise<boolean>`), matching firebase-js-sdk task semantics. Remove `await`, `.then()`, and `.catch()` from these control calls and use the returned boolean directly.
635+
- `cancel()` delegates to the native SDK. Android cancels active uploads; iOS active-upload cancel follows the current Firebase Storage iOS SDK 12.15.0 behavior tracked in [firebase-ios-sdk#16353](https://github.com/firebase/firebase-ios-sdk/issues/16353).
636+
616637
# Authentication
617638

618639
The namespaced API for `@react-native-firebase/auth` has been **removed**. This package is **modular-only** — use `getAuth()` / `initializeAuth()` and root-level helper functions.
@@ -667,7 +688,7 @@ The namespaced API for `@react-native-firebase/firestore` has been **removed**.
667688
| `firestore().collection(...)` | `collection(getFirestore(), ...)` |
668689
| `firestore().doc(...)` | `doc(getFirestore(), ...)` |
669690
| `firestore().batch()` | `writeBatch(getFirestore())` |
670-
| `firestore().runTransaction(...)` | `runTransaction(getFirestore(), ...)` |
691+
| `firestore().runTransaction(...)` | `runTransaction(getFirestore(), updateFunction, options?)` |
671692
| `firestore().useEmulator(...)` | `connectFirestoreEmulator(getFirestore(), ...)` |
672693
| `firestore().settings(...)` | `initializeFirestore(app, settings, databaseId?)` |
673694
| `firestore.FieldValue` / `firestore.Timestamp` | `FieldValue`, `Timestamp`, `FieldPath`, `Bytes`, `GeoPoint`, `Filter` (named exports) |
@@ -676,7 +697,9 @@ The namespaced API for `@react-native-firebase/firestore` has been **removed**.
676697
## Signature changes
677698

678699
- `initializeFirestore(app, settings, databaseId?)` returns `Firestore` synchronously (previously `Promise<Firestore>`). Remove `await` and `.then()`; settings apply on the native bridge after return.
679-
- `aggregateFieldEqual()` is now exported for aggregate queries (firebase-js-sdk parity).
700+
- `TransactionOptions` is now exported. `runTransaction(firestore, updateFunction, options?)` accepts `{ maxAttempts?: number }` and passes the retry limit to the native iOS and Android Firestore SDKs.
701+
- `aggregateFieldEqual()` and `aggregateQuerySnapshotEqual()` are now exported for aggregate query equality checks (firebase-js-sdk parity).
702+
- FieldValue `maximum(n)` and `minimum(n)` sentinels from firebase-js-sdk 12.15.0 are not exported yet. Android Firebase Firestore SDK 34.15.0 supports them, but iOS Firebase Firestore SDK 12.15.0 does not expose matching `FIRFieldValue` factories, so React Native Firebase waits for cross-platform support.
680703

681704
## Example
682705

@@ -742,6 +765,8 @@ For each modular-only package you use:
742765
| `storage` | `firebase.storage()`, default `storage()`, `FirebaseStorageTypes`, instance/reference methods | `getStorage()`, `ref`, `uploadBytesResumable`, `getDownloadURL`, `connectStorageEmulator`, `StringFormat`, `TaskEvent`, `TaskState` |
743766
| `firestore` | `firebase.firestore()`, default `firestore()`, `FirebaseFirestoreTypes`, instance methods | `getFirestore()`, `doc`, `collection`, `setDoc`, `writeBatch`, `runTransaction`, `connectFirestoreEmulator`, `FieldValue`, `Timestamp`, `Bytes`, `SDK_VERSION` |
744767

768+
Also remove `await`, `.then()`, and `.catch()` from `UploadTask.pause()`, `UploadTask.resume()`, and `UploadTask.cancel()`. For Firestore transactions, import `TransactionOptions` when you pass `{ maxAttempts }`, and import `aggregateFieldEqual()` / `aggregateQuerySnapshotEqual()` for aggregate equality checks.
769+
745770
## 3. Validate
746771

747772
```bash

okf-bundle/testing/compare-types-work-queue.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,18 @@ Before any item's `implementation`:
5454
| ----- | ----- | ------ | ------- |
5555
| **A** | Tier 1 — types/docs only | **partial** | A1–A5, A7–A8, A10 committed; A6/A9 deferred |
5656
| **B** | Tier 2 — moderate / Phase S | **complete** | B1–B9 committed (B3 ✅ 2026-07-05) |
57-
| **C** | Tier 3 — hard / structural | **in progress** | C1.1 ✅ committed; C1.2 review closed, ready for commit |
57+
| **C** | Tier 3 — hard / structural | **in progress** | C1.1 ✅ committed; C1.2 ✅ committed; C1.2b documented |
5858
| **D** | Tier 4 — document intractable | **queued** ||
5959

6060
---
6161

6262
## Current snapshot
6363

64-
**Label:** `c1.2-implementation-2026-07-05`
64+
**Label:** `pre-merge-doc-review-2026-07-05`
6565

66-
**Next item:** **C1.3–C1.7** (Phase D document-only batch) or pick from queue.
66+
**Next item:** pre-merge review for push readiness.
6767

68-
**Current gates:** C1.1, C1.2, C1.2b all gates **closed**.
68+
**Current gates:** C1.1, C1.2, C1.2b all gates **closed**. v26 migration guide updated for B3, C1.1, C1.2, and C1.2b.
6969

7070
---
7171

0 commit comments

Comments
 (0)