Skip to content

Commit e2f1b1f

Browse files
authored
Preload settings callbacks (#205)
Provide a way for all SDKs to be initialized before they're called by any ReactFire hooks
1 parent f417133 commit e2f1b1f

File tree

2 files changed

+87
-22
lines changed

2 files changed

+87
-22
lines changed

reactfire/firebaseApp/sdk.tsx

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
import { useFirebaseApp, preloadRequest, usePreloadedRequest } from '..';
22

3+
type RemoteConfig = import('firebase/app').remoteConfig.RemoteConfig;
4+
type Storage = import('firebase/app').storage.Storage;
5+
type Firestore = import('firebase/app').firestore.Firestore;
6+
type Performance = import('firebase/app').performance.Performance;
7+
type Messaging = import('firebase/app').messaging.Messaging;
8+
type Functions = import('firebase/app').functions.Functions;
9+
type Database = import('firebase/app').database.Database;
10+
type Auth = import('firebase/app').auth.Auth;
11+
12+
type FirebaseSDK =
13+
| (() => firebase.analytics.Analytics)
14+
| (() => firebase.auth.Auth)
15+
| ((url?: string) => firebase.database.Database)
16+
| (() => firebase.firestore.Firestore)
17+
| ((region?: string) => firebase.functions.Functions)
18+
| (() => firebase.messaging.Messaging)
19+
| (() => firebase.performance.Performance)
20+
| (() => firebase.remoteConfig.RemoteConfig)
21+
| ((url?: string) => firebase.storage.Storage);
22+
323
enum SDK {
424
ANALYTICS = 'analytics',
525
AUTH = 'auth',
@@ -12,14 +32,21 @@ enum SDK {
1232
STORAGE = 'storage'
1333
}
1434

15-
function fetchSDK(sdk: SDK, firebaseApp: firebase.app.App) {
35+
function fetchSDK(
36+
sdk: SDK,
37+
firebaseApp: firebase.app.App,
38+
settingsCallback: (sdk: FirebaseSDK) => Promise<any> | void = () =>
39+
Promise.resolve()
40+
) {
1641
if (!firebaseApp) {
1742
throw new Error('Firebase app was not provided');
1843
}
1944

20-
let sdkPromise;
45+
let sdkPromise: Promise<FirebaseSDK>;
2146

2247
if (firebaseApp[sdk]) {
48+
// Don't apply settings here. Only needed for lazy loaded SDKs.
49+
// If not lazy loaded, user can provide settings as normal
2350
sdkPromise = Promise.resolve(firebaseApp[sdk]);
2451
} else {
2552
switch (sdk) {
@@ -67,8 +94,12 @@ function fetchSDK(sdk: SDK, firebaseApp: firebase.app.App) {
6794
);
6895
break;
6996
}
70-
sdkPromise = sdkPromise.then(() => firebaseApp[sdk]);
97+
sdkPromise = sdkPromise
98+
.then(() => settingsCallback(firebaseApp[sdk]))
99+
.then(() => firebaseApp[sdk]);
71100
}
101+
preloadRequest(() => sdkPromise, `firebase-sdk-${sdk}`);
102+
72103
return sdkPromise;
73104
}
74105

@@ -84,8 +115,11 @@ function useSDK(sdk: SDK, firebaseApp?: firebase.app.App) {
84115
return usePreloadedRequest(result);
85116
}
86117

87-
export function preloadAuth(firebaseApp: firebase.app.App) {
88-
return fetchSDK(SDK.AUTH, firebaseApp);
118+
export function preloadAuth(
119+
firebaseApp: firebase.app.App,
120+
settingsCallback?: (auth: () => Auth) => void
121+
) {
122+
return fetchSDK(SDK.AUTH, firebaseApp, settingsCallback);
89123
}
90124

91125
export function useAuth(firebaseApp?: firebase.app.App) {
@@ -100,56 +134,77 @@ export function useAnalytics(firebaseApp?: firebase.app.App) {
100134
return useSDK(SDK.ANALYTICS, firebaseApp);
101135
}
102136

103-
export function preloadDatabase(firebaseApp: firebase.app.App) {
104-
return fetchSDK(SDK.DATABASE, firebaseApp);
137+
export function preloadDatabase(
138+
firebaseApp: firebase.app.App,
139+
settingsCallback?: (database: () => Database) => void
140+
) {
141+
return fetchSDK(SDK.DATABASE, firebaseApp, settingsCallback);
105142
}
106143

107144
export function useDatabase(firebaseApp?: firebase.app.App) {
108145
return useSDK(SDK.DATABASE, firebaseApp);
109146
}
110147

111-
export function preloadFirestore(firebaseApp: firebase.app.App) {
112-
return fetchSDK(SDK.FIRESTORE, firebaseApp);
148+
export function preloadFirestore(
149+
firebaseApp: firebase.app.App,
150+
settingsCallback?: (firestore: () => Firestore) => Promise<void>
151+
) {
152+
return fetchSDK(SDK.FIRESTORE, firebaseApp, settingsCallback);
113153
}
114154

115155
export function useFirestore(firebaseApp?: firebase.app.App) {
116156
return useSDK(SDK.FIRESTORE, firebaseApp);
117157
}
118158

119-
export function preloadFunctions(firebaseApp: firebase.app.App) {
120-
return fetchSDK(SDK.FUNCTIONS, firebaseApp);
159+
export function preloadFunctions(
160+
firebaseApp?: firebase.app.App,
161+
settingsCallback?: (functions: () => Functions) => void
162+
) {
163+
return fetchSDK(SDK.FUNCTIONS, firebaseApp, settingsCallback);
121164
}
122165

123166
export function useFunctions(firebaseApp?: firebase.app.App) {
124167
return useSDK(SDK.FUNCTIONS, firebaseApp);
125168
}
126169

127-
export function preloadMessaging(firebaseApp: firebase.app.App) {
128-
return fetchSDK(SDK.MESSAGING, firebaseApp);
170+
export function preloadMessaging(
171+
firebaseApp: firebase.app.App,
172+
settingsCallback?: (messaging: () => Messaging) => void
173+
) {
174+
return fetchSDK(SDK.MESSAGING, firebaseApp, settingsCallback);
129175
}
130176

131177
export function useMessaging(firebaseApp?: firebase.app.App) {
132178
return useSDK(SDK.MESSAGING, firebaseApp);
133179
}
134180

135-
export function preloadPerformance(firebaseApp: firebase.app.App) {
136-
return fetchSDK(SDK.PERFORMANCE, firebaseApp);
181+
export function preloadPerformance(
182+
firebaseApp: firebase.app.App,
183+
settingsCallback?: (performance: () => Performance) => void
184+
) {
185+
return fetchSDK(SDK.PERFORMANCE, firebaseApp, settingsCallback);
137186
}
138187

139188
export function usePerformance(firebaseApp?: firebase.app.App) {
140189
return useSDK(SDK.PERFORMANCE, firebaseApp);
141190
}
142191

143-
export function preloadRemoteConfig(firebaseApp: firebase.app.App) {
144-
return fetchSDK(SDK.REMOTE_CONFIG, firebaseApp);
192+
export function preloadRemoteConfig(
193+
firebaseApp: firebase.app.App,
194+
settingsCallback?: (remoteConfig: () => RemoteConfig) => Promise<any>
195+
) {
196+
return fetchSDK(SDK.REMOTE_CONFIG, firebaseApp, settingsCallback);
145197
}
146198

147199
export function useRemoteConfig(firebaseApp?: firebase.app.App) {
148200
return useSDK(SDK.REMOTE_CONFIG, firebaseApp);
149201
}
150202

151-
export function preloadStorage(firebaseApp: firebase.app.App) {
152-
return fetchSDK(SDK.STORAGE, firebaseApp);
203+
export function preloadStorage(
204+
firebaseApp: firebase.app.App,
205+
settingsCallback: (storage: () => Storage) => Promise<void>
206+
) {
207+
return fetchSDK(SDK.STORAGE, firebaseApp, settingsCallback);
153208
}
154209

155210
export function useStorage(firebaseApp?: firebase.app.App) {

sample/src/App.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,21 @@ const Card = ({ title, children }) => {
3838
// fetching them now
3939
const preloadSDKs = firebaseApp => {
4040
return Promise.all([
41-
preloadFirestore(firebaseApp),
41+
preloadFirestore(firebaseApp, firestore => {
42+
return firestore().enablePersistence();
43+
}),
4244
preloadDatabase(firebaseApp),
43-
preloadStorage(firebaseApp),
45+
preloadStorage(firebaseApp, storage => {
46+
storage().setMaxUploadRetryTime(10000);
47+
}),
4448
preloadAuth(firebaseApp),
45-
preloadRemoteConfig(firebaseApp)
49+
preloadRemoteConfig(firebaseApp, remoteConfig => {
50+
remoteConfig().settings = {
51+
minimumFetchIntervalMillis: 10000,
52+
fetchTimeoutMillis: 10000
53+
};
54+
return remoteConfig().fetchAndActivate();
55+
})
4656
]);
4757
};
4858

0 commit comments

Comments
 (0)