import type { AnalyticsAdapter, AnalyticsEvent, IdentifyPayload, ScreenEvent, } from '../types'; export interface FirebaseAdapterOptions { /** * Pass the analytics instance from `@react-native-firebase/analytics`. * * Install peer dependency: * npm install @react-native-firebase/app @react-native-firebase/analytics * * Usage: * import analytics from '@react-native-firebase/analytics'; * createAnalytics({ adapters: [createFirebaseAdapter({ instance: analytics() })] }); */ instance: any; /** * Firebase event names must be ≤40 chars and snake_case. * Set to true to auto-sanitize event names (default: true). */ sanitizeEventNames?: boolean; } function sanitizeName(name: string): string { return name .toLowerCase() .replace(/[^a-z0-9_]/g, '_') .slice(0, 40); } function sanitizeProperties( properties?: Record ): Record | undefined { if (!properties) return undefined; const result: Record = {}; for (const [key, value] of Object.entries(properties)) { const cleanKey = sanitizeName(key); if (typeof value === 'string' || typeof value === 'number') { result[cleanKey] = value; } else { result[cleanKey] = JSON.stringify(value); } } return result; } export function createFirebaseAdapter(options: FirebaseAdapterOptions): AnalyticsAdapter { const { instance, sanitizeEventNames = true } = options; return { name: 'firebase', async initialize() { // Firebase initializes via native modules }, async track(event: AnalyticsEvent) { const name = sanitizeEventNames ? sanitizeName(event.name) : event.name; await instance.logEvent(name, sanitizeProperties(event.properties) ?? {}); }, async screen(event: ScreenEvent) { await instance.logScreenView({ screen_name: event.name, screen_class: event.name, }); }, async identify(payload: IdentifyPayload) { await instance.setUserId(payload.userId); if (payload.traits) { await Promise.all( Object.entries(payload.traits).map(([key, value]) => instance.setUserProperty(sanitizeName(key), String(value)) ) ); } }, async reset() { await instance.setUserId(null); }, }; }