Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 74 additions & 19 deletions reactfire/firebaseApp/sdk.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
import { useFirebaseApp, preloadRequest, usePreloadedRequest } from '..';

type RemoteConfig = import('firebase/app').remoteConfig.RemoteConfig;
type Storage = import('firebase/app').storage.Storage;
type Firestore = import('firebase/app').firestore.Firestore;
type Performance = import('firebase/app').performance.Performance;
type Messaging = import('firebase/app').messaging.Messaging;
type Functions = import('firebase/app').functions.Functions;
type Database = import('firebase/app').database.Database;
type Auth = import('firebase/app').auth.Auth;

type FirebaseSDK =
| (() => firebase.analytics.Analytics)
| (() => firebase.auth.Auth)
| ((url?: string) => firebase.database.Database)
| (() => firebase.firestore.Firestore)
| ((region?: string) => firebase.functions.Functions)
| (() => firebase.messaging.Messaging)
| (() => firebase.performance.Performance)
| (() => firebase.remoteConfig.RemoteConfig)
| ((url?: string) => firebase.storage.Storage);

enum SDK {
ANALYTICS = 'analytics',
AUTH = 'auth',
Expand All @@ -12,14 +32,21 @@ enum SDK {
STORAGE = 'storage'
}

function fetchSDK(sdk: SDK, firebaseApp: firebase.app.App) {
function fetchSDK(
sdk: SDK,
firebaseApp: firebase.app.App,
settingsCallback: (sdk: FirebaseSDK) => Promise<any> | void = () =>
Promise.resolve()
) {
if (!firebaseApp) {
throw new Error('Firebase app was not provided');
}

let sdkPromise;
let sdkPromise: Promise<FirebaseSDK>;

if (firebaseApp[sdk]) {
// Don't apply settings here. Only needed for lazy loaded SDKs.
// If not lazy loaded, user can provide settings as normal
sdkPromise = Promise.resolve(firebaseApp[sdk]);
} else {
switch (sdk) {
Expand Down Expand Up @@ -67,8 +94,12 @@ function fetchSDK(sdk: SDK, firebaseApp: firebase.app.App) {
);
break;
}
sdkPromise = sdkPromise.then(() => firebaseApp[sdk]);
sdkPromise = sdkPromise
.then(() => settingsCallback(firebaseApp[sdk]))
.then(() => firebaseApp[sdk]);
}
preloadRequest(() => sdkPromise, `firebase-sdk-${sdk}`);

return sdkPromise;
}

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

export function preloadAuth(firebaseApp: firebase.app.App) {
return fetchSDK(SDK.AUTH, firebaseApp);
export function preloadAuth(
firebaseApp: firebase.app.App,
settingsCallback?: (auth: () => Auth) => void
) {
return fetchSDK(SDK.AUTH, firebaseApp, settingsCallback);
}

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

export function preloadDatabase(firebaseApp: firebase.app.App) {
return fetchSDK(SDK.DATABASE, firebaseApp);
export function preloadDatabase(
firebaseApp: firebase.app.App,
settingsCallback?: (database: () => Database) => void
) {
return fetchSDK(SDK.DATABASE, firebaseApp, settingsCallback);
}

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

export function preloadFirestore(firebaseApp: firebase.app.App) {
return fetchSDK(SDK.FIRESTORE, firebaseApp);
export function preloadFirestore(
firebaseApp: firebase.app.App,
settingsCallback?: (firestore: () => Firestore) => Promise<void>
) {
return fetchSDK(SDK.FIRESTORE, firebaseApp, settingsCallback);
}

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

export function preloadFunctions(firebaseApp: firebase.app.App) {
return fetchSDK(SDK.FUNCTIONS, firebaseApp);
export function preloadFunctions(
firebaseApp?: firebase.app.App,
settingsCallback?: (functions: () => Functions) => void
) {
return fetchSDK(SDK.FUNCTIONS, firebaseApp, settingsCallback);
}

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

export function preloadMessaging(firebaseApp: firebase.app.App) {
return fetchSDK(SDK.MESSAGING, firebaseApp);
export function preloadMessaging(
firebaseApp: firebase.app.App,
settingsCallback?: (messaging: () => Messaging) => void
) {
return fetchSDK(SDK.MESSAGING, firebaseApp, settingsCallback);
}

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

export function preloadPerformance(firebaseApp: firebase.app.App) {
return fetchSDK(SDK.PERFORMANCE, firebaseApp);
export function preloadPerformance(
firebaseApp: firebase.app.App,
settingsCallback?: (performance: () => Performance) => void
) {
return fetchSDK(SDK.PERFORMANCE, firebaseApp, settingsCallback);
}

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

export function preloadRemoteConfig(firebaseApp: firebase.app.App) {
return fetchSDK(SDK.REMOTE_CONFIG, firebaseApp);
export function preloadRemoteConfig(
firebaseApp: firebase.app.App,
settingsCallback?: (remoteConfig: () => RemoteConfig) => Promise<any>
) {
return fetchSDK(SDK.REMOTE_CONFIG, firebaseApp, settingsCallback);
}

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

export function preloadStorage(firebaseApp: firebase.app.App) {
return fetchSDK(SDK.STORAGE, firebaseApp);
export function preloadStorage(
firebaseApp: firebase.app.App,
settingsCallback: (storage: () => Storage) => Promise<void>
) {
return fetchSDK(SDK.STORAGE, firebaseApp, settingsCallback);
}

export function useStorage(firebaseApp?: firebase.app.App) {
Expand Down
16 changes: 13 additions & 3 deletions sample/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,21 @@ const Card = ({ title, children }) => {
// fetching them now
const preloadSDKs = firebaseApp => {
return Promise.all([
preloadFirestore(firebaseApp),
preloadFirestore(firebaseApp, firestore => {
return firestore().enablePersistence();
}),
preloadDatabase(firebaseApp),
preloadStorage(firebaseApp),
preloadStorage(firebaseApp, storage => {
storage().setMaxUploadRetryTime(10000);
}),
preloadAuth(firebaseApp),
preloadRemoteConfig(firebaseApp)
preloadRemoteConfig(firebaseApp, remoteConfig => {
remoteConfig().settings = {
minimumFetchIntervalMillis: 10000,
fetchTimeoutMillis: 10000
};
return remoteConfig().fetchAndActivate();
})
]);
};

Expand Down