Skip to content

Commit fc8b839

Browse files
refactor(database)!: migrate to TypeScript (#8977)
* refactor(database): split modular and namespaced entrypoints * refactor(database): split types for modular and namespaced * refactor(database): type namespaced module bridge * refactor(database): compare script using firebase database web types * refactor(database): convert remaining package sources to TypeScript * refactor(database): align modular API with firebase-js-sdk * chore(database): reduce compare-types drift from firebase-js-sdk BREAKING CHANGE: database types now match firebase-js-sdk as closely as possible 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 Database: * removed the modular ServerValue named export from @react-native-firebase/database; consumers must use serverTimestamp() / increment() instead. * changed modular goOffline(db) and goOnline(db) so they no longer return a chainable value, which breaks consumer code that awaits them or calls .then(...) on them. * aligned the modular TypeScript surface with the firebase-js-sdk, so modular types like DatabaseReference, Query, DataSnapshot, OnDisconnect, and QueryConstraint no longer expose the older namespaced instance-style API in their public typings; TypeScript consumers will need to switch to the function-based modular helpers. * corrected getServerTime(db) to a synchronous Date return in the modular type surface, so TypeScript consumers that previously treated it as promise-like will need to update their code.
1 parent 7cf9502 commit fc8b839

43 files changed

Lines changed: 3266 additions & 3377 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: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type { PackageConfig } from '../../src/types';
2+
3+
const config: PackageConfig = {
4+
nameMapping: {},
5+
missingInRN: [],
6+
extraInRN: [
7+
{
8+
name: 'setPersistenceEnabled',
9+
reason:
10+
'RN Firebase-specific helper for configuring native database ' +
11+
'persistence. The firebase-js-sdk modular API does not expose this ' +
12+
'standalone function.',
13+
},
14+
{
15+
name: 'setLoggingEnabled',
16+
reason:
17+
'RN Firebase-specific helper for toggling native database logging. ' +
18+
'The firebase-js-sdk modular API exposes `enableLogging()` instead.',
19+
},
20+
{
21+
name: 'setPersistenceCacheSizeBytes',
22+
reason:
23+
'RN Firebase-specific helper for configuring the native persistence ' +
24+
'cache size. No equivalent standalone modular helper exists in the ' +
25+
'firebase-js-sdk.',
26+
},
27+
{
28+
name: 'getServerTime',
29+
reason:
30+
'RN Firebase-specific helper that reads native server time offset and ' +
31+
'returns the current server timestamp. No equivalent modular helper ' +
32+
'exists in the firebase-js-sdk.',
33+
},
34+
{
35+
name: 'keepSynced',
36+
reason:
37+
'RN Firebase-specific modular helper mirroring the native/database ' +
38+
'offline sync API. The firebase-js-sdk modular package does not export ' +
39+
'a standalone `keepSynced()` function.',
40+
},
41+
],
42+
differentShape: [
43+
{
44+
name: 'EmulatorMockTokenOptions',
45+
reason:
46+
'RN Firebase reuses the local `FirebaseIdToken` alias in ' +
47+
'`Partial<FirebaseIdToken>`, while the snapshot inlines the token ' +
48+
'shape so compare-types does not treat the helper alias as an extra export. ' +
49+
'The two types are structurally equivalent.',
50+
},
51+
],
52+
};
53+
54+
export default config;
Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
/**
2+
* Public types snapshot from the Firebase JS SDK (@firebase/database).
3+
*
4+
* Source: firebase-js-sdk API report for "@firebase/database"
5+
* Modality: modular (tree-shakeable) API only
6+
*/
7+
8+
import { FirebaseApp } from '@firebase/app';
9+
10+
export declare type EmulatorMockTokenOptions = ({ user_id: string } | { sub: string }) &
11+
Partial<{
12+
iss: string;
13+
aud: string;
14+
sub: string;
15+
iat: number;
16+
exp: number;
17+
user_id: string;
18+
auth_time: number;
19+
provider_id?: 'anonymous';
20+
email?: string;
21+
email_verified?: boolean;
22+
phone_number?: string;
23+
name?: string;
24+
picture?: string;
25+
firebase: {
26+
sign_in_provider:
27+
| 'custom'
28+
| 'email'
29+
| 'password'
30+
| 'phone'
31+
| 'anonymous'
32+
| 'google.com'
33+
| 'facebook.com'
34+
| 'github.com'
35+
| 'twitter.com'
36+
| 'microsoft.com'
37+
| 'apple.com';
38+
identities?: {
39+
custom?: string[];
40+
email?: string[];
41+
password?: string[];
42+
phone?: string[];
43+
anonymous?: string[];
44+
'google.com'?: string[];
45+
'facebook.com'?: string[];
46+
'github.com'?: string[];
47+
'twitter.com'?: string[];
48+
'microsoft.com'?: string[];
49+
'apple.com'?: string[];
50+
};
51+
};
52+
uid?: never;
53+
[claim: string]: unknown;
54+
}>;
55+
56+
export declare function child(parent: DatabaseReference, path: string): DatabaseReference;
57+
58+
export declare function connectDatabaseEmulator(
59+
db: Database,
60+
host: string,
61+
port: number,
62+
options?: {
63+
mockUserToken?: EmulatorMockTokenOptions | string;
64+
},
65+
): void;
66+
67+
export declare class Database {
68+
readonly app: FirebaseApp;
69+
readonly type: 'database';
70+
}
71+
72+
export declare interface DatabaseReference extends Query {
73+
readonly key: string | null;
74+
readonly parent: DatabaseReference | null;
75+
readonly root: DatabaseReference;
76+
}
77+
78+
export declare class DataSnapshot {
79+
readonly key: string | null;
80+
readonly priority: string | number | null;
81+
readonly ref: DatabaseReference;
82+
readonly size: number;
83+
child(path: string): DataSnapshot;
84+
exists(): boolean;
85+
exportVal(): any;
86+
forEach(action: (child: IteratedDataSnapshot) => boolean | void): boolean;
87+
hasChild(path: string): boolean;
88+
hasChildren(): boolean;
89+
toJSON(): object | null;
90+
val(): any;
91+
}
92+
93+
export declare function enableLogging(enabled: boolean, persistent?: boolean): any;
94+
export declare function enableLogging(logger: (message: string) => unknown): any;
95+
96+
export declare function endAt(
97+
value: number | string | boolean | null,
98+
key?: string,
99+
): QueryConstraint;
100+
101+
export declare function endBefore(
102+
value: number | string | boolean | null,
103+
key?: string,
104+
): QueryConstraint;
105+
106+
export declare function equalTo(
107+
value: number | string | boolean | null,
108+
key?: string,
109+
): QueryConstraint;
110+
111+
export declare type EventType =
112+
| 'value'
113+
| 'child_added'
114+
| 'child_changed'
115+
| 'child_moved'
116+
| 'child_removed';
117+
118+
export declare function forceLongPolling(): void;
119+
export declare function forceWebSockets(): void;
120+
121+
export declare function get(query: Query): Promise<DataSnapshot>;
122+
export declare function getDatabase(app?: FirebaseApp, url?: string): Database;
123+
export declare function goOffline(db: Database): void;
124+
export declare function goOnline(db: Database): void;
125+
export declare function increment(delta: number): object;
126+
127+
export declare interface IteratedDataSnapshot extends DataSnapshot {
128+
key: string;
129+
}
130+
131+
export declare function limitToFirst(limit: number): QueryConstraint;
132+
export declare function limitToLast(limit: number): QueryConstraint;
133+
134+
export declare interface ListenOptions {
135+
readonly onlyOnce?: boolean;
136+
}
137+
138+
export declare function off(
139+
query: Query,
140+
eventType?: EventType,
141+
callback?: (snapshot: DataSnapshot, previousChildName?: string | null) => unknown,
142+
): void;
143+
144+
export declare function onChildAdded(
145+
query: Query,
146+
callback: (snapshot: DataSnapshot, previousChildName?: string | null) => unknown,
147+
cancelCallback?: (error: Error) => unknown,
148+
): Unsubscribe;
149+
export declare function onChildAdded(
150+
query: Query,
151+
callback: (snapshot: DataSnapshot, previousChildName: string | null) => unknown,
152+
options: ListenOptions,
153+
): Unsubscribe;
154+
export declare function onChildAdded(
155+
query: Query,
156+
callback: (snapshot: DataSnapshot, previousChildName: string | null) => unknown,
157+
cancelCallback: (error: Error) => unknown,
158+
options: ListenOptions,
159+
): Unsubscribe;
160+
161+
export declare function onChildChanged(
162+
query: Query,
163+
callback: (snapshot: DataSnapshot, previousChildName: string | null) => unknown,
164+
cancelCallback?: (error: Error) => unknown,
165+
): Unsubscribe;
166+
export declare function onChildChanged(
167+
query: Query,
168+
callback: (snapshot: DataSnapshot, previousChildName: string | null) => unknown,
169+
options: ListenOptions,
170+
): Unsubscribe;
171+
export declare function onChildChanged(
172+
query: Query,
173+
callback: (snapshot: DataSnapshot, previousChildName: string | null) => unknown,
174+
cancelCallback: (error: Error) => unknown,
175+
options: ListenOptions,
176+
): Unsubscribe;
177+
178+
export declare function onChildMoved(
179+
query: Query,
180+
callback: (snapshot: DataSnapshot, previousChildName: string | null) => unknown,
181+
cancelCallback?: (error: Error) => unknown,
182+
): Unsubscribe;
183+
export declare function onChildMoved(
184+
query: Query,
185+
callback: (snapshot: DataSnapshot, previousChildName: string | null) => unknown,
186+
options: ListenOptions,
187+
): Unsubscribe;
188+
export declare function onChildMoved(
189+
query: Query,
190+
callback: (snapshot: DataSnapshot, previousChildName: string | null) => unknown,
191+
cancelCallback: (error: Error) => unknown,
192+
options: ListenOptions,
193+
): Unsubscribe;
194+
195+
export declare function onChildRemoved(
196+
query: Query,
197+
callback: (snapshot: DataSnapshot) => unknown,
198+
cancelCallback?: (error: Error) => unknown,
199+
): Unsubscribe;
200+
export declare function onChildRemoved(
201+
query: Query,
202+
callback: (snapshot: DataSnapshot) => unknown,
203+
options: ListenOptions,
204+
): Unsubscribe;
205+
export declare function onChildRemoved(
206+
query: Query,
207+
callback: (snapshot: DataSnapshot) => unknown,
208+
cancelCallback: (error: Error) => unknown,
209+
options: ListenOptions,
210+
): Unsubscribe;
211+
212+
export declare class OnDisconnect {
213+
cancel(): Promise<void>;
214+
remove(): Promise<void>;
215+
set(value: unknown): Promise<void>;
216+
setWithPriority(value: unknown, priority: string | number | null): Promise<void>;
217+
update(values: object): Promise<void>;
218+
}
219+
220+
export declare function onDisconnect(ref: DatabaseReference): OnDisconnect;
221+
222+
export declare function onValue(
223+
query: Query,
224+
callback: (snapshot: DataSnapshot) => unknown,
225+
cancelCallback?: (error: Error) => unknown,
226+
): Unsubscribe;
227+
export declare function onValue(
228+
query: Query,
229+
callback: (snapshot: DataSnapshot) => unknown,
230+
options: ListenOptions,
231+
): Unsubscribe;
232+
export declare function onValue(
233+
query: Query,
234+
callback: (snapshot: DataSnapshot) => unknown,
235+
cancelCallback: (error: Error) => unknown,
236+
options: ListenOptions,
237+
): Unsubscribe;
238+
239+
export declare function orderByChild(path: string): QueryConstraint;
240+
export declare function orderByKey(): QueryConstraint;
241+
export declare function orderByPriority(): QueryConstraint;
242+
export declare function orderByValue(): QueryConstraint;
243+
244+
export declare function push(parent: DatabaseReference, value?: unknown): ThenableReference;
245+
246+
export declare interface Query {
247+
isEqual(other: Query | null): boolean;
248+
readonly ref: DatabaseReference;
249+
toJSON(): string;
250+
toString(): string;
251+
}
252+
253+
export declare function query(query: Query, ...queryConstraints: QueryConstraint[]): Query;
254+
255+
export declare abstract class QueryConstraint {
256+
abstract readonly type: QueryConstraintType;
257+
}
258+
259+
export declare type QueryConstraintType =
260+
| 'endAt'
261+
| 'endBefore'
262+
| 'startAt'
263+
| 'startAfter'
264+
| 'limitToFirst'
265+
| 'limitToLast'
266+
| 'orderByChild'
267+
| 'orderByKey'
268+
| 'orderByPriority'
269+
| 'orderByValue'
270+
| 'equalTo';
271+
272+
export declare function ref(db: Database, path?: string): DatabaseReference;
273+
export declare function refFromURL(db: Database, url: string): DatabaseReference;
274+
export declare function remove(ref: DatabaseReference): Promise<void>;
275+
276+
export declare function runTransaction(
277+
ref: DatabaseReference,
278+
transactionUpdate: (currentData: any) => unknown,
279+
options?: TransactionOptions,
280+
): Promise<TransactionResult>;
281+
282+
export declare function serverTimestamp(): object;
283+
export declare function set(ref: DatabaseReference, value: unknown): Promise<void>;
284+
export declare function setPriority(
285+
ref: DatabaseReference,
286+
priority: string | number | null,
287+
): Promise<void>;
288+
export declare function setWithPriority(
289+
ref: DatabaseReference,
290+
value: unknown,
291+
priority: string | number | null,
292+
): Promise<void>;
293+
294+
export declare function startAfter(
295+
value: number | string | boolean | null,
296+
key?: string,
297+
): QueryConstraint;
298+
export declare function startAt(
299+
value?: number | string | boolean | null,
300+
key?: string,
301+
): QueryConstraint;
302+
303+
export declare interface ThenableReference
304+
extends DatabaseReference, Pick<Promise<DatabaseReference>, 'then' | 'catch'> {
305+
key: string;
306+
parent: DatabaseReference;
307+
}
308+
309+
export declare interface TransactionOptions {
310+
readonly applyLocally?: boolean;
311+
}
312+
313+
export declare class TransactionResult {
314+
readonly committed: boolean;
315+
readonly snapshot: DataSnapshot;
316+
toJSON(): object;
317+
}
318+
319+
export declare type Unsubscribe = () => void;
320+
321+
export declare function update(ref: DatabaseReference, values: object): Promise<void>;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ export function parseModularFiles(
368368
if (!sf) {
369369
throw new Error(
370370
`Could not load source file: ${filePath}\n` +
371-
`Make sure the package has been built (yarn build:all:build).`,
371+
`Make sure the package has been built (run 'yarn' in root of repository).`,
372372
);
373373
}
374374
collectExportsFromSourceFile(sf, result);

0 commit comments

Comments
 (0)