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
JavaScript
'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