UNPKG

@angular/fire

Version:

The official Angular library for Firebase.

290 lines (281 loc) 15 kB
import { ɵgetAllInstancesOf, ɵisAnalyticsSupportedFactory, ɵzoneWrap, VERSION, ɵgetDefaultInstanceOf, ɵAngularFireSchedulers } from '@angular/fire'; import { timer, from, of } from 'rxjs'; import { concatMap, distinct, filter, switchMap, map, groupBy, mergeMap, distinctUntilChanged, startWith, pairwise } from 'rxjs/operators'; import * as i0 from '@angular/core'; import { Injectable, Optional, InjectionToken, APP_INITIALIZER, NgModule, NgZone, Injector } from '@angular/core'; import { FirebaseApp, FirebaseApps } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; import { __awaiter } from 'tslib'; import * as i1$1 from '@angular/router'; import { ActivationEnd, ɵEmptyOutletComponent } from '@angular/router'; import * as i2 from '@angular/platform-browser'; import { getAnalytics as getAnalytics$1, initializeAnalytics as initializeAnalytics$1, logEvent as logEvent$1, setAnalyticsCollectionEnabled as setAnalyticsCollectionEnabled$1, setCurrentScreen as setCurrentScreen$1, settings as settings$1, setUserId as setUserId$1, setUserProperties as setUserProperties$1 } from 'firebase/analytics'; export * from 'firebase/analytics'; import * as i1 from '@angular/fire/auth'; import { authState } from '@angular/fire/auth'; class Analytics { constructor(analytics) { return analytics; } } const ANALYTICS_PROVIDER_NAME = 'analytics'; class AnalyticsInstances { constructor() { return ɵgetAllInstancesOf(ANALYTICS_PROVIDER_NAME); } } const analyticInstance$ = timer(0, 300).pipe(concatMap(() => fromgetAllInstancesOf(ANALYTICS_PROVIDER_NAME))), distinct()); const isSupported = ɵisAnalyticsSupportedFactory.async; // DO NOT MODIFY, this file is autogenerated by tools/build.ts const getAnalytics = ɵzoneWrap(getAnalytics$1, true); const initializeAnalytics = ɵzoneWrap(initializeAnalytics$1, true); const logEvent = ɵzoneWrap(logEvent$1, true); const setAnalyticsCollectionEnabled = ɵzoneWrap(setAnalyticsCollectionEnabled$1, true); const setCurrentScreen = ɵzoneWrap(setCurrentScreen$1, true); const settings = ɵzoneWrap(settings$1, true); const setUserId = ɵzoneWrap(setUserId$1, true); const setUserProperties = ɵzoneWrap(setUserProperties$1, true); class UserTrackingService { constructor(auth, zone, injector) { this.disposables = []; registerVersion('angularfire', VERSION.full, 'user-tracking'); let resolveInitialized; this.initialized = zone.runOutsideAngular(() => new Promise(resolve => { resolveInitialized = resolve; })); // The APP_INITIALIZER that is making isSupported() sync for the sake of convenient DI // may not be done when services are initialized. Guard the functionality by first ensuring // that the (global) promise has resolved, then get Analytics from the injector. isSupported().then(() => { const analytics = injector.get(Analytics); if (analytics) { this.disposables = [ // TODO add credential tracking back in authState(auth).subscribe(user => { setUserId(analytics, user === null || user === void 0 ? void 0 : user.uid); resolveInitialized(); }), ]; } else { resolveInitialized(); } }); } ngOnDestroy() { this.disposables.forEach(it => it.unsubscribe()); } } UserTrackingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: UserTrackingService, deps: [{ token: i1.Auth }, { token: i0.NgZone }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); UserTrackingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: UserTrackingService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: UserTrackingService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.Auth }, { type: i0.NgZone }, { type: i0.Injector }]; } }); const FIREBASE_EVENT_ORIGIN_KEY = 'firebase_event_origin'; const FIREBASE_PREVIOUS_SCREEN_CLASS_KEY = 'firebase_previous_class'; const FIREBASE_PREVIOUS_SCREEN_INSTANCE_ID_KEY = 'firebase_previous_id'; const FIREBASE_PREVIOUS_SCREEN_NAME_KEY = 'firebase_previous_screen'; const FIREBASE_SCREEN_CLASS_KEY = 'firebase_screen_class'; const FIREBASE_SCREEN_INSTANCE_ID_KEY = 'firebase_screen_id'; const FIREBASE_SCREEN_NAME_KEY = 'firebase_screen'; const OUTLET_KEY = 'outlet'; const PAGE_PATH_KEY = 'page_path'; const PAGE_TITLE_KEY = 'page_title'; const SCREEN_CLASS_KEY = 'screen_class'; const SCREEN_NAME_KEY = 'screen_name'; const SCREEN_VIEW_EVENT = 'screen_view'; const EVENT_ORIGIN_AUTO = 'auto'; const SCREEN_INSTANCE_DELIMITER = '#'; // this is an INT64 in iOS/Android but use INT32 cause javascript let nextScreenInstanceID = Math.floor(Math.random() * (Math.pow(2, 32) - 1)) - Math.pow(2, 31); const knownScreenInstanceIDs = {}; const getScreenInstanceID = (params) => { // unique the screen class against the outlet name const screenInstanceKey = [ params[SCREEN_CLASS_KEY], params[OUTLET_KEY] ].join(SCREEN_INSTANCE_DELIMITER); if (knownScreenInstanceIDs.hasOwnProperty(screenInstanceKey)) { return knownScreenInstanceIDs[screenInstanceKey]; } else { const ret = nextScreenInstanceID++; knownScreenInstanceIDs[screenInstanceKey] = ret; return ret; } }; const ɵscreenViewEvent = (router, title, componentFactoryResolver) => { const activationEndEvents = router.events.pipe(filter(e => e instanceof ActivationEnd)); return activationEndEvents.pipe(switchMap(activationEnd => { var _a; // router parseUrl is having trouble with outlets when they're empty // e.g, /asdf/1(bob://sally:asdf), so put another slash in when empty const urlTree = router.parseUrl(router.url.replace(/(?:\().+(?:\))/g, a => a.replace('://', ':///'))); const pagePath = ((_a = urlTree.root.children[activationEnd.snapshot.outlet]) === null || _a === void 0 ? void 0 : _a.toString()) || ''; const actualSnapshot = router.routerState.root.children.map(it => it).find(it => it.outlet === activationEnd.snapshot.outlet); if (!actualSnapshot) { return of(null); } let actualDeep = actualSnapshot; while (actualDeep.firstChild) { actualDeep = actualDeep.firstChild; } const screenName = actualDeep.pathFromRoot.map(s => { var _a; return (_a = s.routeConfig) === null || _a === void 0 ? void 0 : _a.path; }).filter(it => it).join('/') || '/'; const params = { [SCREEN_NAME_KEY]: screenName, [PAGE_PATH_KEY]: `/${pagePath}`, [FIREBASE_EVENT_ORIGIN_KEY]: EVENT_ORIGIN_AUTO, [FIREBASE_SCREEN_NAME_KEY]: screenName, [OUTLET_KEY]: activationEnd.snapshot.outlet }; if (title) { params[PAGE_TITLE_KEY] = title.getTitle(); } let component = actualSnapshot.component; if (component) { if (component === ɵEmptyOutletComponent) { let deepSnapshot = activationEnd.snapshot; // TODO when might there be mutple children, different outlets? explore while (deepSnapshot.firstChild) { deepSnapshot = deepSnapshot.firstChild; } component = deepSnapshot.component; } } else { component = activationEnd.snapshot.component; } if (typeof component === 'string') { return of(Object.assign(Object.assign({}, params), { [SCREEN_CLASS_KEY]: component })); } else if (component) { const componentFactory = componentFactoryResolver.resolveComponentFactory(component); return of(Object.assign(Object.assign({}, params), { [SCREEN_CLASS_KEY]: componentFactory.selector })); } // lazy loads cause extra activations, ignore return of(null); }), filter(it => !!it), map(params => (Object.assign({ [FIREBASE_SCREEN_CLASS_KEY]: params[SCREEN_CLASS_KEY], [FIREBASE_SCREEN_INSTANCE_ID_KEY]: getScreenInstanceID(params) }, params))), groupBy(it => it[OUTLET_KEY]), mergeMap(it => it.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)), startWith(undefined), pairwise(), map(([prior, current]) => prior ? Object.assign({ [FIREBASE_PREVIOUS_SCREEN_CLASS_KEY]: prior[SCREEN_CLASS_KEY], [FIREBASE_PREVIOUS_SCREEN_NAME_KEY]: prior[SCREEN_NAME_KEY], [FIREBASE_PREVIOUS_SCREEN_INSTANCE_ID_KEY]: prior[FIREBASE_SCREEN_INSTANCE_ID_KEY] }, current) : current)))); }; class ScreenTrackingService { constructor(router, title, componentFactoryResolver, zone, userTrackingService, injector) { registerVersion('angularfire', VERSION.full, 'screen-tracking'); // The APP_INITIALIZER that is making isSupported() sync for the sake of convenient DI // may not be done when services are initialized. Guard the functionality by first ensuring // that the (global) promise has resolved, then get Analytics from the injector. isSupported().then(() => { const analytics = injector.get(Analytics); if (!router || !analytics) { return; } zone.runOutsideAngular(() => { this.disposable = ɵscreenViewEvent(router, title, componentFactoryResolver).pipe(switchMap((params) => __awaiter(this, void 0, void 0, function* () { if (userTrackingService) { yield userTrackingService.initialized; } return logEvent(analytics, SCREEN_VIEW_EVENT, params); }))).subscribe(); }); }); } ngOnDestroy() { if (this.disposable) { this.disposable.unsubscribe(); } } } ScreenTrackingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: ScreenTrackingService, deps: [{ token: i1$1.Router, optional: true }, { token: i2.Title, optional: true }, { token: i0.ComponentFactoryResolver }, { token: i0.NgZone }, { token: UserTrackingService, optional: true }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); ScreenTrackingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: ScreenTrackingService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: ScreenTrackingService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1$1.Router, decorators: [{ type: Optional }] }, { type: i2.Title, decorators: [{ type: Optional }] }, { type: i0.ComponentFactoryResolver }, { type: i0.NgZone }, { type: UserTrackingService, decorators: [{ type: Optional }] }, { type: i0.Injector }]; } }); const PROVIDED_ANALYTICS_INSTANCES = new InjectionToken('angularfire2.analytics-instances'); function defaultAnalyticsInstanceFactory(provided, defaultApp) { if (!ɵisAnalyticsSupportedFactory.sync()) { return null; } const defaultAnalytics = ɵgetDefaultInstanceOf(ANALYTICS_PROVIDER_NAME, provided, defaultApp); return defaultAnalytics && new Analytics(defaultAnalytics); } function analyticsInstanceFactory(fn) { return (zone, injector) => { if (!ɵisAnalyticsSupportedFactory.sync()) { return null; } const analytics = zone.runOutsideAngular(() => fn(injector)); return new Analytics(analytics); }; } const ANALYTICS_INSTANCES_PROVIDER = { provide: AnalyticsInstances, deps: [ [new Optional(), PROVIDED_ANALYTICS_INSTANCES], ] }; const DEFAULT_ANALYTICS_INSTANCE_PROVIDER = { provide: Analytics, useFactory: defaultAnalyticsInstanceFactory, deps: [ [new Optional(), PROVIDED_ANALYTICS_INSTANCES], FirebaseApp, ] }; class AnalyticsModule { constructor(_screenTrackingService, _userTrackingService) { registerVersion('angularfire', VERSION.full, 'analytics'); } } AnalyticsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AnalyticsModule, deps: [{ token: ScreenTrackingService, optional: true }, { token: UserTrackingService, optional: true }], target: i0.ɵɵFactoryTarget.NgModule }); AnalyticsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AnalyticsModule }); AnalyticsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AnalyticsModule, providers: [ DEFAULT_ANALYTICS_INSTANCE_PROVIDER, ANALYTICS_INSTANCES_PROVIDER, { provide: APP_INITIALIZER, useValue: ɵisAnalyticsSupportedFactory.async, multi: true, } ] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AnalyticsModule, decorators: [{ type: NgModule, args: [{ providers: [ DEFAULT_ANALYTICS_INSTANCE_PROVIDER, ANALYTICS_INSTANCES_PROVIDER, { provide: APP_INITIALIZER, useValue: ɵisAnalyticsSupportedFactory.async, multi: true, } ] }] }], ctorParameters: function () { return [{ type: ScreenTrackingService, decorators: [{ type: Optional }] }, { type: UserTrackingService, decorators: [{ type: Optional }] }]; } }); function provideAnalytics(fn, ...deps) { return { ngModule: AnalyticsModule, providers: [{ provide: PROVIDED_ANALYTICS_INSTANCES, useFactory: analyticsInstanceFactory(fn), multi: true, deps: [ NgZone, Injector, ɵAngularFireSchedulers, FirebaseApps, ...deps, ] }] }; } /** * Generated bundle index. Do not edit. */ export { Analytics, AnalyticsInstances, AnalyticsModule, ScreenTrackingService, UserTrackingService, analyticInstance$, getAnalytics, initializeAnalytics, isSupported, logEvent, provideAnalytics, setAnalyticsCollectionEnabled, setCurrentScreen, setUserId, setUserProperties, settings, ɵscreenViewEvent }; //# sourceMappingURL=angular-fire-analytics.js.map