Skip to content

Commit d38edde

Browse files
committed
test(app): add app module type comparison config
Register @react-native-firebase/app in compare:types and document 25 modular API deltas against firebase-js-sdk. Type SDK_VERSION as string.
1 parent 05cdf79 commit d38edde

4 files changed

Lines changed: 172 additions & 8 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/**
2+
* Known differences between firebase-js-sdk @firebase/app and
3+
* @react-native-firebase/app modular API.
4+
*
5+
* Each entry must have a `name` and a `reason`. Any undocumented
6+
* difference or stale entry will fail `yarn compare:types`.
7+
*/
8+
9+
import type { PackageConfig } from '../src/types';
10+
11+
const config: PackageConfig = {
12+
nameMapping: {},
13+
14+
missingInRN: [
15+
{
16+
name: 'initializeServerApp',
17+
reason:
18+
'firebase-js-sdk server-side rendering entry point. Not applicable to React Native.',
19+
},
20+
{
21+
name: 'FirebaseAppSettings',
22+
reason:
23+
'Settings type for firebase-js-sdk `FirebaseServerApp`. RN Firebase has no server-app API.',
24+
},
25+
{
26+
name: 'FirebaseError',
27+
reason:
28+
'firebase-js-sdk base error class. RN Firebase uses `ReactNativeFirebase.NativeFirebaseError` from the native bridge instead.',
29+
},
30+
{
31+
name: 'FirebaseOptions',
32+
reason:
33+
'firebase-js-sdk options interface. RN Firebase uses `ReactNativeFirebase.FirebaseAppOptions` (extends the same fields with RN-specific optional keys).',
34+
},
35+
{
36+
name: 'FirebaseServerApp',
37+
reason:
38+
'firebase-js-sdk server-side app instance type. Not applicable to React Native.',
39+
},
40+
{
41+
name: 'FirebaseServerAppSettings',
42+
reason:
43+
'Settings type for firebase-js-sdk server apps. Not applicable to React Native.',
44+
},
45+
],
46+
47+
extraInRN: [
48+
{
49+
name: 'setReactNativeAsyncStorage',
50+
reason:
51+
'RN Firebase-specific hook to wire `@react-native-async-storage/async-storage` into the firebase-js-sdk Other/Hermes persistence path.',
52+
},
53+
{
54+
name: 'metaGetAll',
55+
reason:
56+
'RN Firebase native bridge helper — reads all entries from the native Firebase metadata store.',
57+
},
58+
{
59+
name: 'jsonGetAll',
60+
reason:
61+
'RN Firebase native bridge helper — reads all entries from the native JSON config store.',
62+
},
63+
{
64+
name: 'preferencesClearAll',
65+
reason:
66+
'RN Firebase native bridge helper — clears native shared preferences used by Firebase.',
67+
},
68+
{
69+
name: 'preferencesGetAll',
70+
reason:
71+
'RN Firebase native bridge helper — reads all native shared preference entries.',
72+
},
73+
{
74+
name: 'preferencesSetBool',
75+
reason:
76+
'RN Firebase native bridge helper — sets a native boolean preference.',
77+
},
78+
{
79+
name: 'preferencesSetString',
80+
reason:
81+
'RN Firebase native bridge helper — sets a native string preference.',
82+
},
83+
{
84+
name: 'getUtils',
85+
reason:
86+
'RN Firebase entry point for the native Utils module (Play Services, file paths, etc.). No firebase-js-sdk modular equivalent.',
87+
},
88+
{
89+
name: 'FilePath',
90+
reason:
91+
'RN Firebase native device file-path constants for Storage and similar file-based APIs.',
92+
},
93+
{
94+
name: 'LogCallbackParams',
95+
reason:
96+
'RN Firebase log-handler callback payload type exported for modular `setLogLevel` wiring.',
97+
},
98+
{
99+
name: 'LogCallback',
100+
reason:
101+
'RN Firebase log-handler callback type exported for modular logging configuration.',
102+
},
103+
{
104+
name: 'LogOptions',
105+
reason:
106+
'RN Firebase log-handler options type exported for modular logging configuration.',
107+
},
108+
],
109+
110+
differentShape: [
111+
{
112+
name: 'deleteApp',
113+
reason:
114+
'Parameter type is `ReactNativeFirebase.FirebaseApp` instead of firebase-js-sdk `FirebaseApp`. Runtime behavior matches.',
115+
},
116+
{
117+
name: 'getApp',
118+
reason:
119+
'Return type is `ReactNativeFirebase.FirebaseApp` instead of firebase-js-sdk `FirebaseApp`. Runtime behavior matches.',
120+
},
121+
{
122+
name: 'getApps',
123+
reason:
124+
'Return type is `ReactNativeFirebase.FirebaseApp[]` instead of firebase-js-sdk `FirebaseApp[]`. Runtime behavior matches.',
125+
},
126+
{
127+
name: 'initializeApp',
128+
reason:
129+
'Returns `Promise<ReactNativeFirebase.FirebaseApp>` because initialization crosses the native bridge. Accepts `ReactNativeFirebase.FirebaseAppOptions` and optional `ReactNativeFirebase.FirebaseAppConfig` (name / auth domain) instead of firebase-js-sdk `(FirebaseOptions, string)` only.',
130+
},
131+
{
132+
name: 'registerVersion',
133+
reason:
134+
'Returns `Promise<void>` in RN Firebase vs `void` in firebase-js-sdk. Bridge-forced async today — Phase S sync-conversion candidate when native work is in-memory only.',
135+
},
136+
{
137+
name: 'setLogLevel',
138+
reason:
139+
'Parameter type is `ReactNativeFirebase.LogLevelString` instead of firebase-js-sdk `LogLevelString`. Accepted values match (`debug`, `verbose`, `info`, `warn`, `error`, `silent`).',
140+
},
141+
{
142+
name: 'FirebaseApp',
143+
reason:
144+
'RN Firebase exports the `ReactNativeFirebase.FirebaseApp` class/interface from shared app declarations instead of re-exporting firebase-js-sdk `FirebaseApp`.',
145+
},
146+
],
147+
};
148+
149+
export default config;

.github/scripts/compare-types/src/registry.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import remoteConfigConfig from '../configs/remote-config';
2121
import authConfig from '../configs/auth';
2222
import installationsConfig from '../configs/installations';
2323
import perfConfig from '../configs/perf-config';
24+
import appConfig from '../configs/app';
2425

2526
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..');
2627

@@ -103,6 +104,20 @@ function optionalFirebasePackage(
103104
}
104105

105106
export const packages: PackageEntry[] = [
107+
{
108+
name: 'app',
109+
firebaseSdkTypesPaths: [requiredFirebaseTypes('app')],
110+
rnFirebaseModularFiles: [
111+
path.join(rnDist('app'), 'modular.d.ts'),
112+
path.join(rnDist('app'), 'index.d.ts'),
113+
],
114+
rnFirebaseSupportFiles: [
115+
path.join(rnDist('app'), 'types', 'app.d.ts'),
116+
path.join(rnDist('app'), 'types', 'internal.d.ts'),
117+
path.join(rnDist('app'), 'FirebaseApp.d.ts'),
118+
],
119+
config: appConfig,
120+
},
106121
{
107122
name: 'auth',
108123
firebaseSdkTypesPaths: [requiredFirebaseTypes('auth')],

okf-bundle/new-architecture/migration-work-queue.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ timestamp: 2026-06-26T00:00:00Z
88

99
# TurboModule migration — work queue
1010

11-
> **IN PROGRESS (2026-06-30):** Phase **0** (`app` TurboModules) — **done**. Phase **0.1** (`app` compare:types) — **queued**. Decisions: [architecture-decisions.md](architecture-decisions.md).
11+
> **IN PROGRESS (2026-06-30):** Phase **0** (`app` TurboModules) — **done**. Phase **0.1** (`app` compare:types) — **commit** pending. Decisions: [architecture-decisions.md](architecture-decisions.md).
1212
> **Goal/order:** app foundation → hard probe → easy wins → remaining complex → sync conversion → coordinated break → cleanup (events, shared-state encapsulation). Decisions: [architecture-decisions.md](architecture-decisions.md). Links: [implementation workflow](turbomodule-implementation-workflow.md), [change authoring](../testing/change-authoring-workflow.md), [functions reference](../../../packages/functions/) ([PR #8603](https://github.com/invertase/react-native-firebase/pull/8603)).
1313
1414
Ephemeral tracker; see [OKF policy](../documentation-policy.md).
@@ -161,7 +161,7 @@ Pick **one** of `firestore` or `auth` in Phase 1 (firestore = multi-module + pip
161161
| Phase | Focus | Status | Packages |
162162
|-------|--------|--------|----------|
163163
| **0** | App foundation + unified resolver | **done** | `app` |
164-
| **0.1** | App modular type parity (`compare:types`) | **queued** | `app`[§ Phase 0.1](#phase-01-app-comparetypes) |
164+
| **0.1** | App modular type parity (`compare:types`) | **commit pending** | `app`[§ Phase 0.1](#phase-01-app-comparetypes) |
165165
| **1** | Hard probe | queued | `firestore` **or** `auth` — pick one |
166166
| **2** | Easy wins | queued | `installations`, `perf`, `in-app-messaging`, `app-distribution`, `ml` |
167167
| **3** | Moderate | queued | `app-check`, `remote-config`, `analytics`, `crashlytics`, `storage` |
@@ -207,7 +207,7 @@ The "keep async if it does network/IO/disk" rule in the discriminator **assumes*
207207
| Column | What to record |
208208
|--------|----------------|
209209
| Method | RNFB API + package |
210-
| compare:types signal | Is it currently recorded as an async-vs-sync delta? (note: `app` registers in Phase **0.1**; other packages may still be unregistered — do not treat the config list as the full candidate set) |
210+
| compare:types signal | Is it currently recorded as an async-vs-sync delta? (note: `app` is registered as of Phase **0.1**; other packages may still be unregistered — do not treat the config list as the full candidate set) |
211211
| firebase-js-sdk behavior | What the web SDK actually does under the hood — **in-memory/cached** vs **deferred IO**. Cite the SDK source. |
212212
| RNFB native behavior | What our native shell does for the same result — pure in-memory (SDK getter, parse, cached field) vs real IO (network, disk, keychain, Play Services). |
213213
| Verdict | `convert` (both in-memory) / `keep-async` (either side does real IO) / `needs-native-change` (web is in-memory but our native is needlessly IO and could be made in-memory) |
@@ -267,11 +267,11 @@ Skip steps 1–2 when spec shape is known (most Tier D packages).
267267

268268
## Current snapshot
269269

270-
**Label:** `phase-0-committed`; **harness:** full (committed defaults)
270+
**Label:** `phase-0.1-compare-types`; **harness:** n/a (types-only)
271271

272-
**Next item:** Phase **0.1** `app` compare:types**implementation**
272+
**Next item:** Phase **0.1** `app` compare:types**commit**
273273

274-
**Current gates:** Phase 0 all **closed** · Phase 0.1 all **open**
274+
**Current gates:** Phase 0 all **closed** · Phase 0.1 `review_gate` **closed** · `commit_gate` **open**
275275

276276
**Arbiter gate:**
277277

@@ -280,7 +280,7 @@ Skip steps 1–2 when spec shape is known (most Tier D packages).
280280
|------|------|----------------------|---------------|---------------|------------------|-------------------|------------------|-------|
281281
| Design review | DR | n/a | n/a | n/a | done | none | none | ✅ Adversarial review complete. |
282282
| Phase 0 `app` TurboModules | P0 | **closed** | **closed** | **closed** | done | `full` | `feat(app): migrate app modules to TurboModules incl general migration infra` | Committed 2026-06-30. |
283-
| Phase 0.1 `app` compare:types | P0.1 | **open** | **open** | **open** | `implementation` | `none` | `test(app): add app module type comparison config` | Queued after P0. |
283+
| Phase 0.1 `app` compare:types | P0.1 | **closed** | **closed** | **open** | `commit` | `none` | `test(app): add app module type comparison config` | 25 deltas documented; `SDK_VERSION` typed `string`; compare:types green for `app`. |
284284

285285
---
286286

packages/app/lib/modular.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ export function preferencesSetString(key: string, value: string): Promise<void>
166166
return getAppModule().preferencesSetString(key, value);
167167
}
168168

169-
export const SDK_VERSION = sdkVersion;
169+
export const SDK_VERSION: string = sdkVersion;
170170

171171
/**
172172
* Returns the {@link Utils.Module} instance for the default or given {@link ReactNativeFirebase.FirebaseApp}.

0 commit comments

Comments
 (0)