UNPKG

capacitor-firebase-kit

Version:

Provider-less Firebase Kit - Universal Firebase services integration for React, React Native, and Capacitor apps

1,305 lines (1,293 loc) 113 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var core = require('@capacitor/core'); class PlatformDetector { constructor() { this.cachedPlatform = null; } detect() { if (this.cachedPlatform) { return this.cachedPlatform; } const info = { platform: 'web', isWeb: false, isReactNative: false, isCapacitor: false, isNode: false, hasDOM: false, }; // Check if we're in Node.js environment if (typeof process !== 'undefined' && process.versions && process.versions.node) { info.platform = 'node'; info.isNode = true; this.cachedPlatform = info; return info; } // Check for DOM availability info.hasDOM = typeof window !== 'undefined' && typeof document !== 'undefined'; // Check for React Native if (typeof global !== 'undefined' && global.nativePerformanceNow) { info.platform = 'react-native'; info.isReactNative = true; this.cachedPlatform = info; return info; } // Check for Capacitor if (info.hasDOM && window.Capacitor) { info.platform = 'capacitor'; info.isCapacitor = true; this.cachedPlatform = info; return info; } // Default to web if (info.hasDOM) { info.platform = 'web'; info.isWeb = true; } this.cachedPlatform = info; return info; } reset() { this.cachedPlatform = null; } } const platformDetector = new PlatformDetector(); class FirebaseKitSingleton { constructor() { this.initialized = false; this.config = null; this.adapter = null; this.serviceInstances = new Map(); } static getInstance() { if (!FirebaseKitSingleton.instance) { FirebaseKitSingleton.instance = new FirebaseKitSingleton(); } return FirebaseKitSingleton.instance; } async initialize(config) { if (this.initialized) { console.warn('FirebaseKit is already initialized'); return; } this.config = config; const platformInfo = platformDetector.detect(); // Dynamically load the appropriate adapter based on platform this.adapter = await this.loadPlatformAdapter(platformInfo.platform); await this.adapter.initialize(config); this.initialized = true; } async loadPlatformAdapter(platform) { switch (platform) { case 'web': const { WebAdapter } = await Promise.resolve().then(function () { return webAdapter; }); return new WebAdapter(); case 'react-native': const { ReactNativeAdapter } = await Promise.resolve().then(function () { return reactNativeAdapter; }); return new ReactNativeAdapter(); case 'capacitor': const { CapacitorAdapter } = await Promise.resolve().then(function () { return capacitorAdapter; }); return new CapacitorAdapter(); case 'node': const { NodeAdapter } = await Promise.resolve().then(function () { return nodeAdapter; }); return new NodeAdapter(); default: throw new Error(`Unsupported platform: ${platform}`); } } async getService(serviceName) { if (!this.initialized || !this.adapter) { throw new Error('FirebaseKit must be initialized before accessing services'); } // Check if service instance already exists if (this.serviceInstances.has(serviceName)) { return this.serviceInstances.get(serviceName); } // Lazy load the service const service = await this.adapter.getService(serviceName); this.serviceInstances.set(serviceName, service); return service; } isInitialized() { return this.initialized; } getConfig() { return this.config; } reset() { this.initialized = false; this.config = null; this.adapter = null; this.serviceInstances.clear(); } } const firebaseKitSingleton = FirebaseKitSingleton.getInstance(); // Main FirebaseKit class class FirebaseKit { async initialize(config) { await firebaseKitSingleton.initialize(config); } get analytics() { if (!this.analyticsService) { this.analyticsService = { logEvent: async (eventName, eventParams) => { const service = await firebaseKitSingleton.getService('analytics'); return service.logEvent(eventName, eventParams); }, setUserId: async (userId) => { const service = await firebaseKitSingleton.getService('analytics'); return service.setUserId(userId); }, setUserProperties: async (properties) => { const service = await firebaseKitSingleton.getService('analytics'); return service.setUserProperties(properties); }, setCurrentScreen: async (screenName, screenClassOverride) => { const service = await firebaseKitSingleton.getService('analytics'); return service.setCurrentScreen(screenName, screenClassOverride); }, setEnabled: async (enabled) => { const service = await firebaseKitSingleton.getService('analytics'); return service.setEnabled(enabled); }, isSupported: async () => { const service = await firebaseKitSingleton.getService('analytics'); return service.isSupported(); }, }; } return this.analyticsService; } get appCheck() { if (!this.appCheckService) { this.appCheckService = { initialize: async (options) => { const service = await firebaseKitSingleton.getService('appCheck'); return service.initialize(options); }, getToken: async (forceRefresh) => { const service = await firebaseKitSingleton.getService('appCheck'); return service.getToken(forceRefresh); }, setTokenAutoRefreshEnabled: async (enabled) => { const service = await firebaseKitSingleton.getService('appCheck'); return service.setTokenAutoRefreshEnabled(enabled); }, }; } return this.appCheckService; } get adMob() { if (!this.adMobService) { this.adMobService = { initialize: async (options) => { const service = await firebaseKitSingleton.getService('adMob'); return service.initialize(options); }, showBanner: async (options) => { const service = await firebaseKitSingleton.getService('adMob'); return service.showBanner(options); }, hideBanner: async () => { const service = await firebaseKitSingleton.getService('adMob'); return service.hideBanner(); }, resumeBanner: async () => { const service = await firebaseKitSingleton.getService('adMob'); return service.resumeBanner(); }, removeBanner: async () => { const service = await firebaseKitSingleton.getService('adMob'); return service.removeBanner(); }, prepareInterstitial: async (options) => { const service = await firebaseKitSingleton.getService('adMob'); return service.prepareInterstitial(options); }, showInterstitial: async () => { const service = await firebaseKitSingleton.getService('adMob'); return service.showInterstitial(); }, prepareRewardVideoAd: async (options) => { const service = await firebaseKitSingleton.getService('adMob'); return service.prepareRewardVideoAd(options); }, showRewardVideoAd: async () => { const service = await firebaseKitSingleton.getService('adMob'); return service.showRewardVideoAd(); }, setApplicationMuted: async (muted) => { const service = await firebaseKitSingleton.getService('adMob'); return service.setApplicationMuted(muted); }, setApplicationVolume: async (volume) => { const service = await firebaseKitSingleton.getService('adMob'); return service.setApplicationVolume(volume); }, }; } return this.adMobService; } get crashlytics() { if (!this.crashlyticsService) { this.crashlyticsService = { crash: async () => { const service = await firebaseKitSingleton.getService('crashlytics'); return service.crash(); }, setUserId: async (userId) => { const service = await firebaseKitSingleton.getService('crashlytics'); return service.setUserId(userId); }, log: async (message) => { const service = await firebaseKitSingleton.getService('crashlytics'); return service.log(message); }, setEnabled: async (enabled) => { const service = await firebaseKitSingleton.getService('crashlytics'); return service.setEnabled(enabled); }, isEnabled: async () => { const service = await firebaseKitSingleton.getService('crashlytics'); return service.isEnabled(); }, recordException: async (error) => { const service = await firebaseKitSingleton.getService('crashlytics'); return service.recordException(error); }, setCustomKey: async (key, value) => { const service = await firebaseKitSingleton.getService('crashlytics'); return service.setCustomKey(key, value); }, setCustomKeys: async (customKeys) => { const service = await firebaseKitSingleton.getService('crashlytics'); return service.setCustomKeys(customKeys); }, }; } return this.crashlyticsService; } get performance() { if (!this.performanceService) { this.performanceService = { startTrace: async (traceName) => { const service = await firebaseKitSingleton.getService('performance'); return service.startTrace(traceName); }, stopTrace: async (traceName) => { const service = await firebaseKitSingleton.getService('performance'); return service.stopTrace(traceName); }, incrementMetric: async (traceName, metricName, value) => { const service = await firebaseKitSingleton.getService('performance'); return service.incrementMetric(traceName, metricName, value); }, setEnabled: async (enabled) => { const service = await firebaseKitSingleton.getService('performance'); return service.setEnabled(enabled); }, isEnabled: async () => { const service = await firebaseKitSingleton.getService('performance'); return service.isEnabled(); }, }; } return this.performanceService; } get remoteConfig() { if (!this.remoteConfigService) { this.remoteConfigService = { initialize: async (options) => { const service = await firebaseKitSingleton.getService('remoteConfig'); return service.initialize(options); }, fetchAndActivate: async () => { const service = await firebaseKitSingleton.getService('remoteConfig'); return service.fetchAndActivate(); }, fetchConfig: async () => { const service = await firebaseKitSingleton.getService('remoteConfig'); return service.fetchConfig(); }, activate: async () => { const service = await firebaseKitSingleton.getService('remoteConfig'); return service.activate(); }, getValue: async (key) => { const service = await firebaseKitSingleton.getService('remoteConfig'); return service.getValue(key); }, getString: async (key) => { const service = await firebaseKitSingleton.getService('remoteConfig'); return service.getString(key); }, getNumber: async (key) => { const service = await firebaseKitSingleton.getService('remoteConfig'); return service.getNumber(key); }, getBoolean: async (key) => { const service = await firebaseKitSingleton.getService('remoteConfig'); return service.getBoolean(key); }, setLogLevel: async (logLevel) => { const service = await firebaseKitSingleton.getService('remoteConfig'); return service.setLogLevel(logLevel); }, }; } return this.remoteConfigService; } } // Export singleton instance const firebaseKit = new FirebaseKit(); /** * Creates a proxy for the Firebase Kit plugin that provides the nested service structure. * This proxy organizes the flat plugin interface into logical service groups for better developer experience. * * @param plugin The native plugin instance * @returns FirebaseKitPlugin with organized service structure * @since 1.0.0 */ function createFirebaseKitProxy(plugin) { // Create App Check service proxy const appCheck = { /** * Initialize Firebase App Check with the specified provider. * This must be called before using any other Firebase services. * * @param options Configuration options for App Check initialization * @returns Promise that resolves when App Check is initialized * @since 1.0.0 * @example * ```typescript * await FirebaseKit.appCheck.initialize({ * provider: 'playIntegrity', * isTokenAutoRefreshEnabled: true * }); * ``` */ async initialize(options) { return plugin.appCheckInitialize(options); }, /** * Get an App Check token for API requests. * * @param options Optional token generation options * @returns Promise with the App Check token result * @since 1.0.0 * @example * ```typescript * const { token } = await FirebaseKit.appCheck.getToken(); * ``` */ async getToken(options) { return plugin.appCheckGetToken(options); }, /** * Enable or disable automatic token refresh. * * @param options Configuration for auto-refresh * @returns Promise that resolves when setting is updated * @since 1.0.0 * @example * ```typescript * await FirebaseKit.appCheck.setTokenAutoRefreshEnabled({ enabled: true }); * ``` */ async setTokenAutoRefreshEnabled(options) { return plugin.appCheckSetTokenAutoRefreshEnabled(options); }, /** * Add a listener for App Check token changes. * * @param eventName The event to listen for * @param listenerFunc Callback function to handle token updates * @returns Promise with listener handle for cleanup * @since 1.0.0 * @example * ```typescript * const listener = await FirebaseKit.appCheck.addListener( * 'appCheckTokenChanged', * (token) => console.log('Token updated:', token) * ); * ``` */ async addListener(eventName, listenerFunc) { return plugin.addListener(eventName, listenerFunc); }, }; // Create AdMob service proxy const adMob = { /** * Initialize Google AdMob with configuration options. * Should be called before showing any ads. * * @param options Optional initialization configuration * @returns Promise that resolves when AdMob is initialized * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.initialize({ * requestTrackingAuthorization: true, * testingDevices: ['device_id_hash'] * }); * ``` */ async initialize(options) { return plugin.adMobInitialize(options); }, /** * Request consent information from Google UMP SDK. * Required for GDPR compliance. * * @param options Optional consent request configuration * @returns Promise with consent information * @since 1.0.0 * @example * ```typescript * const consent = await FirebaseKit.adMob.requestConsentInfo({ * tagForUnderAgeOfConsent: false * }); * ``` */ async requestConsentInfo(options) { return plugin.adMobRequestConsentInfo(options); }, /** * Show the consent form to the user. * * @returns Promise with consent status after form completion * @since 1.0.0 * @example * ```typescript * const status = await FirebaseKit.adMob.showConsentForm(); * ``` */ async showConsentForm() { return plugin.adMobShowConsentForm(); }, /** * Reset consent information (for testing purposes). * * @returns Promise that resolves when consent info is reset * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.resetConsentInfo(); * ``` */ async resetConsentInfo() { return plugin.adMobResetConsentInfo(); }, /** * Set global request configuration for all ad requests. * * @param options Request configuration options * @returns Promise that resolves when configuration is set * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.setRequestConfiguration({ * testDeviceIds: ['test_device_id'] * }); * ``` */ async setRequestConfiguration(options) { return plugin.adMobSetRequestConfiguration(options); }, /** * Show a banner ad at the specified position. * * @param options Banner ad configuration * @returns Promise that resolves when banner is shown * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.showBanner({ * adId: 'ca-app-pub-xxx/yyy', * adSize: 'BANNER', * position: 'BOTTOM_CENTER' * }); * ``` */ async showBanner(options) { return plugin.adMobShowBanner(options); }, /** * Hide the currently displayed banner ad. * * @returns Promise that resolves when banner is hidden * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.hideBanner(); * ``` */ async hideBanner() { return plugin.adMobHideBanner(); }, /** * Remove the banner ad from the view hierarchy. * * @returns Promise that resolves when banner is removed * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.removeBanner(); * ``` */ async removeBanner() { return plugin.adMobRemoveBanner(); }, /** * Load an interstitial ad for later display. * * @param options Interstitial ad configuration * @returns Promise that resolves when ad is loaded * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.loadInterstitial({ * adId: 'ca-app-pub-xxx/yyy' * }); * ``` */ async loadInterstitial(options) { return plugin.adMobLoadInterstitial(options); }, /** * Show the previously loaded interstitial ad. * * @returns Promise that resolves when ad is shown * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.showInterstitial(); * ``` */ async showInterstitial() { return plugin.adMobShowInterstitial(); }, /** * Load a rewarded ad for later display. * * @param options Rewarded ad configuration * @returns Promise that resolves when ad is loaded * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.loadRewarded({ * adId: 'ca-app-pub-xxx/yyy' * }); * ``` */ async loadRewarded(options) { return plugin.adMobLoadRewarded(options); }, /** * Show the previously loaded rewarded ad. * * @returns Promise that resolves when ad is shown * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.showRewarded(); * ``` */ async showRewarded() { return plugin.adMobShowRewarded(); }, /** * Load a rewarded interstitial ad for later display. * * @param options Rewarded interstitial ad configuration * @returns Promise that resolves when ad is loaded * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.loadRewardedInterstitial({ * adId: 'ca-app-pub-xxx/yyy' * }); * ``` */ async loadRewardedInterstitial(options) { return plugin.adMobLoadRewardedInterstitial(options); }, /** * Show the previously loaded rewarded interstitial ad. * * @returns Promise that resolves when ad is shown * @since 1.0.0 * @example * ```typescript * await FirebaseKit.adMob.showRewardedInterstitial(); * ``` */ async showRewardedInterstitial() { return plugin.adMobShowRewardedInterstitial(); }, /** * Add a listener for AdMob events. * * @param eventName The AdMob event to listen for * @param listenerFunc Callback function to handle the event * @returns Promise with listener handle for cleanup * @since 1.0.0 * @example * ```typescript * const listener = await FirebaseKit.adMob.addListener( * 'bannerAdLoaded', * (info) => console.log('Banner loaded:', info) * ); * ``` */ async addListener(eventName, listenerFunc) { return plugin.addListener(eventName, listenerFunc); }, }; // Create Crashlytics service proxy const crashlytics = { /** * Force a crash for testing purposes. * Should only be used in development builds. * * @returns Promise that resolves before the crash * @since 1.0.0 * @example * ```typescript * if (__DEV__) { * await FirebaseKit.crashlytics.crash(); * } * ``` */ async crash() { return plugin.crashlyticsCrash(); }, /** * Force a crash with a custom message. * Should only be used in development builds. * * @param options Configuration with crash message * @returns Promise that resolves before the crash * @since 1.0.0 * @example * ```typescript * if (__DEV__) { * await FirebaseKit.crashlytics.forceCrash({ * message: 'Test crash for debugging' * }); * } * ``` */ async forceCrash(options) { return plugin.crashlyticsForceCrash(options); }, /** * Log a custom message to Crashlytics. * These messages appear in crash reports to help with debugging. * * @param options Configuration with log message * @returns Promise that resolves when message is logged * @since 1.0.0 * @example * ```typescript * await FirebaseKit.crashlytics.log({ * message: 'User clicked the purchase button' * }); * ``` */ async log(options) { return plugin.crashlyticsLog(options); }, /** * Log a non-fatal exception with details. * * @param options Exception details and stack trace * @returns Promise that resolves when exception is logged * @since 1.0.0 * @example * ```typescript * await FirebaseKit.crashlytics.logException({ * message: 'API call failed', * code: 'NETWORK_ERROR', * stackTrace: [{ * fileName: 'api.service.ts', * lineNumber: 42, * methodName: 'fetchData' * }] * }); * ``` */ async logException(options) { return plugin.crashlyticsLogException(options); }, /** * Set a user identifier for crash reports. * * @param options Configuration with user ID * @returns Promise that resolves when user ID is set * @since 1.0.0 * @example * ```typescript * await FirebaseKit.crashlytics.setUserId({ * userId: 'user_123' * }); * ``` */ async setUserId(options) { return plugin.crashlyticsSetUserId(options); }, /** * Set custom key-value pairs for crash reports. * * @param options Configuration with custom attributes * @returns Promise that resolves when custom keys are set * @since 1.0.0 * @example * ```typescript * await FirebaseKit.crashlytics.setCustomKeys({ * attributes: { * screen: 'checkout', * user_type: 'premium', * level: 5 * } * }); * ``` */ async setCustomKeys(options) { return plugin.crashlyticsSetCustomKeys(options); }, /** * Enable or disable crash collection. * * @param options Configuration for crash collection * @returns Promise that resolves when setting is updated * @since 1.0.0 * @example * ```typescript * await FirebaseKit.crashlytics.setCrashlyticsCollectionEnabled({ * enabled: true * }); * ``` */ async setCrashlyticsCollectionEnabled(options) { return plugin.crashlyticsSetCrashlyticsCollectionEnabled(options); }, /** * Check if crash collection is enabled. * * @returns Promise with crash collection status * @since 1.0.0 * @example * ```typescript * const { enabled } = await FirebaseKit.crashlytics.isCrashlyticsCollectionEnabled(); * ``` */ async isCrashlyticsCollectionEnabled() { return plugin.crashlyticsIsCrashlyticsCollectionEnabled(); }, /** * Delete unsent crash reports. * * @returns Promise that resolves when reports are deleted * @since 1.0.0 * @example * ```typescript * await FirebaseKit.crashlytics.deleteUnsentReports(); * ``` */ async deleteUnsentReports() { return plugin.crashlyticsDeleteUnsentReports(); }, /** * Send unsent crash reports immediately. * * @returns Promise that resolves when reports are sent * @since 1.0.0 * @example * ```typescript * await FirebaseKit.crashlytics.sendUnsentReports(); * ``` */ async sendUnsentReports() { return plugin.crashlyticsSendUnsentReports(); }, /** * Record a breadcrumb for crash context. * * @param options Breadcrumb configuration * @returns Promise that resolves when breadcrumb is recorded * @since 1.0.0 * @example * ```typescript * await FirebaseKit.crashlytics.recordBreadcrumb({ * name: 'button_click', * params: { button_id: 'checkout' } * }); * ``` */ async recordBreadcrumb(options) { return plugin.crashlyticsRecordBreadcrumb(options); }, }; // Create Performance service proxy const performance = { async initialize(options) { return plugin.performanceInitialize(options); }, async setPerformanceCollectionEnabled(options) { return plugin.performanceSetPerformanceCollectionEnabled(options); }, async isPerformanceCollectionEnabled() { return plugin.performanceIsPerformanceCollectionEnabled(); }, async startTrace(options) { return plugin.performanceStartTrace(options); }, async stopTrace(options) { return plugin.performanceStopTrace(options); }, async incrementMetric(options) { return plugin.performanceIncrementMetric(options); }, async setMetric(options) { return plugin.performanceSetMetric(options); }, async getMetric(options) { return plugin.performanceGetMetric(options); }, async putAttribute(options) { return plugin.performancePutAttribute(options); }, async getAttributes(options) { return plugin.performanceGetAttributes(options); }, async removeAttribute(options) { return plugin.performanceRemoveAttribute(options); }, async startScreenTrace(options) { return plugin.performanceStartScreenTrace(options); }, async stopScreenTrace(options) { return plugin.performanceStopScreenTrace(options); }, async recordNetworkRequest(options) { return plugin.performanceRecordNetworkRequest(options); }, }; // Create Analytics service proxy const analytics = { async initialize(options) { return plugin.analyticsInitialize(options); }, async setCollectionEnabled(options) { return plugin.analyticsSetCollectionEnabled(options); }, async setCurrentScreen(options) { return plugin.analyticsSetCurrentScreen(options); }, async logEvent(options) { return plugin.analyticsLogEvent(options); }, async setUserProperty(options) { return plugin.analyticsSetUserProperty(options); }, async setUserId(options) { return plugin.analyticsSetUserId(options); }, async setSessionTimeoutDuration(options) { return plugin.analyticsSetSessionTimeoutDuration(options); }, async getAppInstanceId() { return plugin.analyticsGetAppInstanceId(); }, async resetAnalyticsData() { return plugin.analyticsResetAnalyticsData(); }, async setConsent(options) { return plugin.analyticsSetConsent(options); }, async setDefaultEventParameters(options) { return plugin.analyticsSetDefaultEventParameters(options); }, }; // Create Remote Config service proxy const remoteConfig = { async initialize(options) { return plugin.remoteConfigInitialize(options); }, async setDefaults(options) { return plugin.remoteConfigSetDefaults(options); }, async fetch(options) { return plugin.remoteConfigFetch(options); }, async activate() { return plugin.remoteConfigActivate(); }, async fetchAndActivate(options) { return plugin.remoteConfigFetchAndActivate(options); }, async getValue(options) { return plugin.remoteConfigGetValue(options); }, async getAll() { return plugin.remoteConfigGetAll(); }, async getSettings() { return plugin.remoteConfigGetSettings(); }, async setSettings(options) { return plugin.remoteConfigSetSettings(options); }, async ensureInitialized() { return plugin.remoteConfigEnsureInitialized(); }, async reset() { return plugin.remoteConfigReset(); }, async addListener(eventName, listenerFunc) { return plugin.addListener(eventName, listenerFunc); }, }; // Return the complete Firebase Kit proxy with all services return { appCheck, adMob, crashlytics, performance, analytics, remoteConfig, }; } /** * Register the legacy Capacitor plugin for backward compatibility * * @deprecated Use the new provider-less `firebaseKit` API instead * @example * ```typescript * // Old way (deprecated) * import { registerCapacitorPlugin } from 'capacitor-firebase-kit'; * const FirebaseKit = registerCapacitorPlugin(); * * // New way (recommended) * import firebaseKit from 'capacitor-firebase-kit'; * await firebaseKit.initialize({ ... }); * ``` */ async function registerCapacitorPlugin() { try { const { registerPlugin } = await import('@capacitor/core'); const FirebaseKitNative = registerPlugin('FirebaseKit', { web: () => Promise.resolve().then(function () { return pluginImplementation; }).then(m => new m.FirebaseKitPluginImplementation()), }); return createFirebaseKitProxy(FirebaseKitNative); } catch (_a) { throw new Error('Capacitor not found. Please install @capacitor/core to use the legacy plugin API.'); } } /** * Common error codes across all services * @since 1.0.0 */ exports.FirebaseKitErrorCode = void 0; (function (FirebaseKitErrorCode) { // General errors FirebaseKitErrorCode["NOT_INITIALIZED"] = "NOT_INITIALIZED"; FirebaseKitErrorCode["INVALID_ARGUMENT"] = "INVALID_ARGUMENT"; FirebaseKitErrorCode["PERMISSION_DENIED"] = "PERMISSION_DENIED"; FirebaseKitErrorCode["UNAVAILABLE"] = "UNAVAILABLE"; FirebaseKitErrorCode["INTERNAL"] = "INTERNAL"; // App Check errors FirebaseKitErrorCode["APP_CHECK_TOKEN_EXPIRED"] = "APP_CHECK_TOKEN_EXPIRED"; FirebaseKitErrorCode["APP_CHECK_PROVIDER_ERROR"] = "APP_CHECK_PROVIDER_ERROR"; // AdMob errors FirebaseKitErrorCode["AD_LOAD_FAILED"] = "AD_LOAD_FAILED"; FirebaseKitErrorCode["AD_SHOW_FAILED"] = "AD_SHOW_FAILED"; FirebaseKitErrorCode["AD_NOT_READY"] = "AD_NOT_READY"; // Remote Config errors FirebaseKitErrorCode["CONFIG_FETCH_FAILED"] = "CONFIG_FETCH_FAILED"; FirebaseKitErrorCode["CONFIG_UPDATE_FAILED"] = "CONFIG_UPDATE_FAILED"; // Platform errors FirebaseKitErrorCode["NOT_SUPPORTED_ON_PLATFORM"] = "NOT_SUPPORTED_ON_PLATFORM"; FirebaseKitErrorCode["WEB_NOT_SUPPORTED"] = "WEB_NOT_SUPPORTED"; })(exports.FirebaseKitErrorCode || (exports.FirebaseKitErrorCode = {})); class PlatformAdapter { constructor() { this.config = null; this.serviceCache = new Map(); } async loadServiceModule(serviceName) { // Base implementation for loading service modules // Subclasses will override this with platform-specific logic throw new Error(`Service ${serviceName} not implemented for this platform`); } validateConfig(config) { if (!config.projectId) { throw new Error('FirebaseKit: projectId is required'); } // Additional validation can be added here } } class WebAdapter extends PlatformAdapter { constructor() { super(...arguments); this.firebaseApp = null; this.loadedSDKs = new Set(); } async initialize(config) { this.validateConfig(config); this.config = config; // Dynamically import Firebase app if (!this.firebaseApp) { try { const firebaseApp = await import('firebase/app'); const { initializeApp, getApps } = firebaseApp; // Check if app is already initialized const apps = getApps(); if (apps.length > 0) { this.firebaseApp = apps[0]; } else { this.firebaseApp = initializeApp(config); } } catch (_a) { console.warn('Firebase SDK not found. Services will load on demand.'); } } } async getService(serviceName) { if (!this.isSupported(serviceName)) { throw new Error(`Service ${serviceName} is not supported on web platform`); } if (this.serviceCache.has(serviceName)) { return this.serviceCache.get(serviceName); } const service = await this.loadServiceModule(serviceName); this.serviceCache.set(serviceName, service); return service; } async loadServiceModule(serviceName) { switch (serviceName) { case 'analytics': return this.loadAnalytics(); case 'appCheck': return this.loadAppCheck(); case 'performance': return this.loadPerformance(); case 'remoteConfig': return this.loadRemoteConfig(); case 'crashlytics': // Crashlytics is not available for web, return a mock return this.createCrashlyticsStub(); case 'adMob': // AdMob is not available for web, return a mock return this.createAdMobStub(); default: throw new Error(`Unknown service: ${serviceName}`); } } async loadAnalytics() { try { const analyticsModule = await import('firebase/analytics'); const { getAnalytics, logEvent, setUserId, setUserProperties, setCurrentScreen } = analyticsModule; if (!this.firebaseApp) { throw new Error('Firebase app not initialized. Please install firebase package.'); } const analytics = getAnalytics(this.firebaseApp); return { logEvent: (eventName, eventParams) => logEvent(analytics, eventName, eventParams), setUserId: (userId) => setUserId(analytics, userId), setUserProperties: (properties) => setUserProperties(analytics, properties), setCurrentScreen: (screenName) => setCurrentScreen(analytics, screenName), setEnabled: async (_enabled) => { console.warn('Analytics.setEnabled is not supported on web'); }, isSupported: async () => ({ isSupported: true }), }; } catch (_a) { throw new Error('Firebase Analytics SDK not installed. Run: npm install firebase'); } } async loadAppCheck() { try { const appCheckModule = await import('firebase/app-check'); const { initializeAppCheck, getToken, ReCaptchaV3Provider, ReCaptchaEnterpriseProvider } = appCheckModule; if (!this.firebaseApp) { throw new Error('Firebase app not initialized. Please install firebase package.'); } let appCheck; return { initialize: async (options) => { var _a; let provider; if (options.provider === 'recaptcha-v3' && options.siteKey) { provider = new ReCaptchaV3Provider(options.siteKey); } else if (options.provider === 'recaptcha-enterprise' && options.siteKey) { provider = new ReCaptchaEnterpriseProvider(options.siteKey); } else { throw new Error('Invalid App Check provider configuration'); } appCheck = initializeAppCheck(this.firebaseApp, { provider, isTokenAutoRefreshEnabled: (_a = options.isTokenAutoRefreshEnabled) !== null && _a !== void 0 ? _a : true, }); }, getToken: async (forceRefresh) => { if (!appCheck) { throw new Error('App Check not initialized'); } const result = await getToken(appCheck, forceRefresh); return { token: result.token }; }, setTokenAutoRefreshEnabled: async (_enabled) => { console.warn('setTokenAutoRefreshEnabled must be set during initialization'); }, }; } catch (_a) { throw new Error('Firebase App Check SDK not installed. Run: npm install firebase'); } } async loadPerformance() { try { const perfModule = await import('firebase/performance'); const { getPerformance, trace } = perfModule; if (!this.firebaseApp) { throw new Error('Firebase app not initialized. Please install firebase package.'); } const perf = getPerformance(this.firebaseApp); return { startTrace: async (traceName) => { const t = trace(perf, traceName); t.start(); return { traceName, traceId: traceName }; }, stopTrace: async (_traceName) => { // Note: Firebase web SDK doesn't provide a way to get existing traces console.warn('Trace stopping not supported in web SDK. Traces auto-complete.'); }, incrementMetric: async (_traceName, _metricName, _value) => { console.warn('Metric increment not supported in web SDK after trace starts.'); }, setEnabled: async (_enabled) => { console.warn('Performance.setEnabled is not supported on web'); }, isEnabled: async () => ({ isEnabled: true }), }; } catch (_a) { throw new Error('Firebase Performance SDK not installed. Run: npm install firebase'); } } async loadRemoteConfig() { try { const remoteConfigModule = await import('firebase/remote-config'); const { getRemoteConfig, fetchAndActivate, getValue, getString, getNumber, getBoolean, setLogLevel } = remoteConfigModule; if (!this.firebaseApp) { throw new Error('Firebase app not initialized. Please install firebase package.'); } const remoteConfig = getRemoteConfig(this.firebaseApp); return { initialize: async (options) => { var _a, _b; remoteConfig.settings.minimumFetchIntervalMillis = (_a = options.minimumFetchIntervalMillis) !== null && _a !== void 0 ? _a : 43200000; remoteConfig.settings.fetchTimeoutMillis = (_b = options.fetchTimeoutMillis) !== null && _b !== void 0 ? _b : 60000; if (options.defaultConfig) { remoteConfig.defaultConfig = options.defaultConfig; } }, fetchAndActivate: async () => { const activated = await fetchAndActivate(remoteConfig); return { activated }; }, fetchConfig: async () => { await remoteConfig.fetch(); }, activate: async () => { const activated = await remoteConfig.activate(); return { activated }; }, getValue: async (key) => { const value = getValue(remoteConfig, key); return { value: value.asString(), source: value.getSource(), }; }, getString: async (key) => { return { value: getString(remoteConfig, key) }; }, getNumber: async (key) => { return { value: getNumber(remoteConfig, key) }; }, getBoolean: async (key) => { return { value: getBoolean(remoteConfig, key) }; }, setLogLevel: async (logLevel) => { setLogLevel(remoteConfig, logLevel); }, }; } catch (_a) { throw new Error('Firebase Remote Config SDK not installed. Run: npm install firebase'); } } createCrashlyticsStub() { console.warn('Crashlytics is not supported on web platform'); return { crash: async () => console.warn('Crashlytics.crash() not supported on web'), setUserId: async (_userId) => console.warn('Crashlytics.setUserId() not supported on web'), log: async (_message) => console.warn('Crashlytics.log() not supported on web'), setEnabled: async (_enabled) => console.warn('Crashlytics.setEnabled() not supported on web'), isEnabled: async () => ({ isEnabled: false }), recordException: async (_error) => console.warn('Crashlytics.recordException() not supported on web'), setCustomKey: async (_key, _value) => console.warn('Crashlytics.setCustomKey() not supported on web'), setCustomKeys: async (_keys) => console.warn('Crashlytics.setCustomKeys() not supported on web'), }; } createAdMobStub() { console.warn('AdMob is not supported on web platform'); return { initialize: async () => console.warn('AdMob.initialize() not supported on web'), showBanner: async () => console.warn('AdMob.showBanner() not supported on web'), hideBanner: async () => console.warn('AdMob.hideBanner() not supported on web'), resumeBanner: async () => console.warn('AdMob.resumeBanner() not supported on web'), removeBanner: async () => console.warn('AdMob.removeBanner() not supported on web'), prepareInterstitial: async () => console.warn('AdMob.prepareInterstitial() not supported on web'), showInterstitial: async () => console.warn('AdMob.showInterstitial() not supported on web'), prepareRewardVideoAd: async () => console.warn('AdMob.prepareRewardVideoAd() not supported on web'), showRewardVideoAd: async () => console.warn('AdMob.showRewardVideoAd() not supported on web'), setApplicationMuted: async () => console.warn('AdMob.setApplicationMuted() not supported on web'), setApplicationVolume: async () => console.warn('AdMob.setApplicationVolume() not supported on web'), }; } isSupported(serviceName) { const supportedServices = [ 'analytics', 'appCheck', 'performance', 'remoteConfig', 'crashlytics', // Returns stub 'adMob', // Returns stub ]; return supportedServices.includes(serviceName); } async cleanup() { this.serviceCache.clear(); this.firebaseApp = null; this.loadedSDKs.clear(); } } var webAdapter = /*#__PURE__*/Object.freeze({ __proto__: null, WebAdapter: WebAdapter }); class ReactNativeAdapter extends PlatformAdapter { async ini