Skip to content

Commit 663b57c

Browse files
refactor(storage)!: migrate to TypeScript and match firebase-js-sdk API (#8824)
Co-authored-by: Mike Hardy <github@mikehardy.net>
1 parent 4f4df78 commit 663b57c

41 files changed

Lines changed: 3821 additions & 1385 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/**
2+
* Known differences between the firebase-js-sdk @firebase/storage public
3+
* API and the @react-native-firebase/storage modular API.
4+
*
5+
* Each entry must have a `name` (the export name) and a `reason` explaining
6+
* why the difference exists. Any difference NOT listed here will cause CI to
7+
* fail so that new drift is caught and deliberately acknowledged.
8+
*
9+
* Sections:
10+
* nameMapping — exports that exist in both packages but under different names
11+
* missingInRN — firebase-js-sdk exports absent from RN Firebase
12+
* extraInRN — RN Firebase exports not present in the firebase-js-sdk
13+
* differentShape — exports present in both but with differing signatures/members
14+
*/
15+
16+
import type { PackageConfig } from '../../src/types';
17+
18+
const config: PackageConfig = {
19+
// ---------------------------------------------------------------------------
20+
// Name mapping
21+
// ---------------------------------------------------------------------------
22+
nameMapping: {},
23+
24+
// ---------------------------------------------------------------------------
25+
// Missing in RN Firebase
26+
// ---------------------------------------------------------------------------
27+
missingInRN: [
28+
{
29+
name: 'StorageError',
30+
reason:
31+
'RN Firebase surfaces Storage failures as `NativeFirebaseError` instances from ' +
32+
'`@react-native-firebase/app` rather than exporting the firebase-js-sdk web ' +
33+
'`StorageError` subclass.',
34+
},
35+
{
36+
name: 'StorageErrorCode',
37+
reason:
38+
'RN Firebase does not export the firebase-js-sdk `StorageErrorCode` enum. ' +
39+
'Errors instead expose native bridge `code` strings via `NativeFirebaseError`.',
40+
},
41+
],
42+
43+
// ---------------------------------------------------------------------------
44+
// Extra in RN Firebase
45+
// ---------------------------------------------------------------------------
46+
extraInRN: [
47+
{
48+
name: 'setMaxOperationRetryTime',
49+
reason:
50+
'RN Firebase-specific function for setting the maximum retry time for ' +
51+
'non-upload/download operations on Android and iOS. The firebase-js-sdk ' +
52+
'exposes this as a writable property on the `FirebaseStorage` instance.',
53+
},
54+
{
55+
name: 'setMaxUploadRetryTime',
56+
reason:
57+
'RN Firebase-specific function for setting the maximum upload retry time ' +
58+
'on Android and iOS. The firebase-js-sdk exposes this as a writable property ' +
59+
'on the `FirebaseStorage` instance.',
60+
},
61+
{
62+
name: 'setMaxDownloadRetryTime',
63+
reason:
64+
'RN Firebase-specific function for setting the maximum download retry time ' +
65+
'on Android and iOS. No direct equivalent exists in the firebase-js-sdk.',
66+
},
67+
{
68+
name: 'putFile',
69+
reason:
70+
'RN Firebase-specific function that uploads a file from a local device path. ' +
71+
'No equivalent exists in the firebase-js-sdk web API.',
72+
},
73+
{
74+
name: 'writeToFile',
75+
reason:
76+
'RN Firebase-specific function that downloads a file to a local device path. ' +
77+
'No equivalent exists in the firebase-js-sdk web API.',
78+
},
79+
{
80+
name: 'TaskSnapshot',
81+
reason:
82+
'RN Firebase-specific interface extending `UploadTaskSnapshot` with an optional ' +
83+
'`error` field for native task error state. No equivalent in the firebase-js-sdk.',
84+
},
85+
{
86+
name: 'TaskResult',
87+
reason:
88+
'RN Firebase type alias for `UploadResult`, kept for API consistency with the ' +
89+
'native task system. No direct equivalent in the firebase-js-sdk.',
90+
},
91+
{
92+
name: 'TaskSnapshotObserver',
93+
reason:
94+
'RN Firebase type alias for `StorageObserver<TaskSnapshot>`. ' +
95+
'No direct equivalent in the firebase-js-sdk.',
96+
},
97+
{
98+
name: 'Task',
99+
reason:
100+
'RN Firebase type alias for `UploadTask`, used as the return type of ' +
101+
'`uploadBytesResumable`, `uploadString`, `putFile`, and `writeToFile`. ' +
102+
'Kept for consistency with the native task system.',
103+
},
104+
{
105+
name: 'Subscribe',
106+
reason:
107+
'RN Firebase-specific generic type for task event subscription functions. ' +
108+
'No direct equivalent in the firebase-js-sdk public API.',
109+
},
110+
{
111+
name: 'NativeFirebaseError',
112+
reason:
113+
'Re-export of the RN Firebase native bridge error type used in place of ' +
114+
'`StorageError` / `FirebaseError`. No equivalent in the firebase-js-sdk.',
115+
},
116+
],
117+
118+
// ---------------------------------------------------------------------------
119+
// Different shape
120+
// ---------------------------------------------------------------------------
121+
differentShape: [
122+
{
123+
name: 'FirebaseStorage',
124+
reason:
125+
'RN Firebase adds a `maxDownloadRetryTime` property (android & iOS only) ' +
126+
'not present in the firebase-js-sdk `FirebaseStorage`. Additionally, ' +
127+
'`maxUploadRetryTime` and `maxOperationRetryTime` are declared `readonly` ' +
128+
'in RN Firebase (they are set via dedicated modular functions) whereas the ' +
129+
'firebase-js-sdk declares them as mutable properties.',
130+
},
131+
{
132+
name: 'StorageObserver',
133+
reason:
134+
'The `error` callback parameter uses `NativeFirebaseError` instead of ' +
135+
'`StorageError`. Both represent Firebase Storage errors but the RN type ' +
136+
'extends the native bridge error structure.',
137+
},
138+
{
139+
name: 'UploadTask',
140+
reason:
141+
'RN Firebase returns `Promise<boolean>` from `cancel()`, `pause()`, and ' +
142+
'`resume()` to communicate asynchronously with the native iOS/Android modules, ' +
143+
'whereas the firebase-js-sdk returns a synchronous `boolean`. Error callback ' +
144+
'types also use `NativeFirebaseError` instead of `StorageError`.',
145+
},
146+
{
147+
name: 'EmulatorMockTokenOptions',
148+
reason:
149+
'The firebase-js-sdk `EmulatorMockTokenOptions` (from `@firebase/util`) is a ' +
150+
'complex type `({ user_id: string } | { sub: string }) & Partial<FirebaseIdToken>` ' +
151+
'representing a full mock JWT payload. RN Firebase defines a simplified version ' +
152+
'`{ mockUserToken?: string | null }` that only accepts a pre-encoded token string, ' +
153+
'since the native bridge does not need to construct JWT payloads directly.',
154+
},
155+
{
156+
name: 'connectStorageEmulator',
157+
reason:
158+
'The optional `options` parameter type differs: the firebase-js-sdk accepts ' +
159+
'`{ mockUserToken?: EmulatorMockTokenOptions | string }` (an inline object ' +
160+
'literal) while RN Firebase accepts its own `EmulatorMockTokenOptions` interface.',
161+
},
162+
{
163+
name: 'getStream',
164+
reason:
165+
'Returns `NodeJS.ReadableStream` in RN Firebase instead of `ReadableStream` ' +
166+
'(the Web Streams API type). The Node.js stream type is used because the ' +
167+
'React Native environment does not have the Web Streams API.',
168+
},
169+
{
170+
name: 'uploadBytes',
171+
reason:
172+
'Returns `Promise<TaskResult>` in RN Firebase instead of `Promise<UploadResult>`. ' +
173+
'`TaskResult` is a type alias for `UploadResult`, so the runtime shape is identical; ' +
174+
'the different name is for consistency with the native task system.',
175+
},
176+
{
177+
name: 'uploadBytesResumable',
178+
reason:
179+
'Returns `Task` in RN Firebase instead of `UploadTask`. `Task` is a type alias ' +
180+
'for `UploadTask`, so the runtime shape is identical; the different name is for ' +
181+
'consistency with the native task system.',
182+
},
183+
{
184+
name: 'uploadString',
185+
reason:
186+
'Returns `Task` in RN Firebase instead of `Promise<UploadResult>` — the upload ' +
187+
'is resumable via the native task system. The `format` parameter is typed as an ' +
188+
"explicit string union `'raw' | 'base64' | 'base64url' | 'data_url'` instead of " +
189+
'the `StringFormat` type alias, which is semantically identical.',
190+
},
191+
{
192+
name: 'TaskEvent',
193+
reason:
194+
"The firebase-js-sdk declares `TaskEvent` as a string literal type `'state_changed'`. " +
195+
'RN Firebase declares it as a const object `{ STATE_CHANGED: "state_changed" }` and ' +
196+
'derives the type via `(typeof TaskEvent)[keyof typeof TaskEvent]`. Both resolve to ' +
197+
"the same value `'state_changed'` at runtime.",
198+
},
199+
{
200+
name: 'TaskState',
201+
reason:
202+
'The firebase-js-sdk declares `TaskState` as a string literal union. RN Firebase ' +
203+
'declares it as a const object and derives the type via ' +
204+
'`(typeof TaskState)[keyof typeof TaskState]`. The RN const additionally includes ' +
205+
"a `CANCELLED` alias (with double-L) for `'canceled'` for backwards compatibility.",
206+
},
207+
],
208+
};
209+
210+
export default config;

0 commit comments

Comments
 (0)