diff --git a/src/firekit.ts b/src/firekit.ts index 38709738..8efcc7b0 100644 --- a/src/firekit.ts +++ b/src/firekit.ts @@ -40,7 +40,7 @@ import { } from 'firebase/firestore'; import { httpsCallable, HttpsCallableResult } from 'firebase/functions'; -import { AuthPersistence, MarkRawConfig, emptyOrgList, initializeFirebaseProject } from './firestore/util'; +import { AuthPersistence, MarkRawConfig, enableOfflineConfig, emptyOrgList, initializeFirebaseProject } from './firestore/util'; import { Assessment, FirebaseProject, @@ -178,6 +178,7 @@ export class RoarFirekit { private _idTokens: { admin?: string; app?: string }; private _initialized: boolean; private _markRawConfig: MarkRawConfig; + private _enableOfflineConfig: enableOfflineConfig = false; private _roarUid?: string; private _superAdmin?: boolean; private _verboseLogging?: boolean; @@ -194,6 +195,7 @@ export class RoarFirekit { markRawConfig = {}, listenerUpdateCallback, emulatorConfig, + enableOfflineConfig, }: { roarConfig: RoarConfig; emulatorConfig?: Emulators; @@ -202,12 +204,14 @@ export class RoarFirekit { markRawConfig?: MarkRawConfig; verboseLogging: boolean; listenerUpdateCallback?: (...args: unknown[]) => void; + enableOfflineConfig?: enableOfflineConfig; }) { this.roarConfig = roarConfig; this.emulatorConfig = emulatorConfig; this._verboseLogging = verboseLogging; this._authPersistence = authPersistence; this._markRawConfig = markRawConfig; + this._enableOfflineConfig = enableOfflineConfig ?? false; this._initialized = false; this._idTokens = {}; // eslint-disable-next-line @typescript-eslint/no-empty-function @@ -240,6 +244,7 @@ export class RoarFirekit { this.emulatorConfig, this._authPersistence, this._markRawConfig, + this._enableOfflineConfig, ); this._initialized = true; diff --git a/src/firestore/util.ts b/src/firestore/util.ts index bbbd5ae8..6a0aee80 100644 --- a/src/firestore/util.ts +++ b/src/firestore/util.ts @@ -1,4 +1,4 @@ -import { getApp, initializeApp } from 'firebase/app'; +import { FirebaseApp, getApp, initializeApp } from 'firebase/app'; import { Auth, browserLocalPersistence, @@ -21,7 +21,7 @@ import _remove from 'lodash/remove'; import { markRaw } from 'vue'; import { str as crc32 } from 'crc-32'; import { OrgLists } from '../interfaces'; -import { connectFirestoreEmulator, Firestore, getFirestore, enableIndexedDbPersistence } from 'firebase/firestore'; +import { connectFirestoreEmulator, Firestore, getFirestore, initializeFirestore, persistentLocalCache } from 'firebase/firestore'; import { type Emulators } from '../firekit'; /** Remove null attributes from an object @@ -116,23 +116,21 @@ export interface MarkRawConfig { auth?: boolean; db?: boolean; functions?: boolean; -} +} -export interface OfflineConfig { - enablePersistence?: boolean; -} +export type enableOfflineConfig = boolean type FirebaseProduct = Auth | Firestore | Functions | FirebaseStorage; /** * Enable offline persistence for Firestore if requested - * @param db - Firestore instance - * @param offlineConfig - Offline configuration options + * @param app - Firebase app instance + * @param enableOfflineConfig - Offline configuration options */ -const enableOfflinePersistence = async (db: Firestore, offlineConfig: OfflineConfig): Promise => { - if (offlineConfig.enablePersistence) { +const enableOfflinePersistence = (app: FirebaseApp): void => { try { - await enableIndexedDbPersistence(db); + // Defaults to single-tab persistence if no tab manager is specified. + initializeFirestore(app, { localCache: persistentLocalCache(/*settings*/{}) }); console.log('Firestore offline persistence enabled'); } catch (error: any) { if (error.code === 'failed-precondition') { @@ -143,7 +141,6 @@ const enableOfflinePersistence = async (db: Firestore, offlineConfig: OfflineCon console.error('Failed to enable persistence:', error); } } - } }; export const initializeFirebaseProject = async ( @@ -152,7 +149,7 @@ export const initializeFirebaseProject = async ( emulatorConfig?: Emulators | undefined, authPersistence = AuthPersistence.session, markRawConfig: MarkRawConfig = {}, - offlineConfig: OfflineConfig = {}, + enableOfflineConfig: enableOfflineConfig = false, ) => { const optionallyMarkRaw = (productKey: string, productInstance: T): T => { if (_get(markRawConfig, productKey)) { @@ -174,7 +171,9 @@ export const initializeFirebaseProject = async ( connectFunctionsEmulator(functions, emulatorConfig.functions.host, emulatorConfig.functions.port); // Enable offline persistence if requested - await enableOfflinePersistence(db, offlineConfig); + if (enableOfflineConfig) { + enableOfflinePersistence(app); + } const originalInfo = console.info; // eslint-disable-next-line @typescript-eslint/no-empty-function @@ -220,7 +219,9 @@ export const initializeFirebaseProject = async ( }; // Enable offline persistence if requested - await enableOfflinePersistence(kit.db, offlineConfig); + if (enableOfflineConfig) { + enableOfflinePersistence(app); + } // Auth state persistence is set with ``setPersistence`` and specifies how a // user session is persisted on a device. We choose in session persistence by diff --git a/src/index.ts b/src/index.ts index 217c3834..eec39ca1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,4 +2,4 @@ export { RoarFirekit } from './firekit'; export { RoarAppkit } from './firestore/app/appkit'; export { RoarAppUser } from './firestore/app/user'; export { RoarTaskVariant } from './firestore/app/task'; -export { emptyOrg, emptyOrgList, getTreeTableOrgs, initializeFirebaseProject, type OfflineConfig } from './firestore/util'; +export { emptyOrg, emptyOrgList, getTreeTableOrgs, initializeFirebaseProject, type enableOfflineConfig } from './firestore/util'; diff --git a/src/levante-firekit.code-workspace b/src/levante-firekit.code-workspace deleted file mode 100644 index e1a7f684..00000000 --- a/src/levante-firekit.code-workspace +++ /dev/null @@ -1,11 +0,0 @@ -{ - "folders": [ - { - "path": ".." - }, - { - "path": "../../firebase-functions" - } - ], - "settings": {} -} \ No newline at end of file