UNPKG

15.5 kBJavaScriptView Raw
1import { __awaiter } from 'tslib';
2import * as i0 from '@angular/core';
3import { InjectionToken, PLATFORM_ID, Injectable, Optional, Inject, NgModule } from '@angular/core';
4import { of, EMPTY } from 'rxjs';
5import { isPlatformBrowser, isPlatformServer } from '@angular/common';
6import { observeOn, switchMap, map, shareReplay } from 'rxjs/operators';
7import * as i2 from '@angular/fire';
8import { VERSION } from '@angular/fire';
9import * as i1 from '@angular/fire/compat';
10import { ɵcacheInstance, ɵlazySDKProxy, ɵapplyMixins } from '@angular/fire/compat';
11import { isSupported } from 'firebase/analytics';
12import * as i2$2 from '@angular/router';
13import * as i3 from '@angular/platform-browser';
14import * as i2$1 from '@angular/fire/compat/auth';
15import firebase from 'firebase/compat/app';
16import { ɵscreenViewEvent } from '@angular/fire/analytics';
17
18// DO NOT MODIFY, this file is autogenerated by tools/build.ts
19// Export a null object with the same keys as firebase/compat/analytics, so Proxy can work with proxy-polyfill in Internet Explorer
20const proxyPolyfillCompat = {
21 app: null,
22 logEvent: null,
23 setCurrentScreen: null,
24 setUserId: null,
25 setUserProperties: null,
26 setAnalyticsCollectionEnabled: null,
27};
28
29const COLLECTION_ENABLED = new InjectionToken('angularfire2.analytics.analyticsCollectionEnabled');
30const APP_VERSION = new InjectionToken('angularfire2.analytics.appVersion');
31const APP_NAME = new InjectionToken('angularfire2.analytics.appName');
32const DEBUG_MODE = new InjectionToken('angularfire2.analytics.debugMode');
33const CONFIG = new InjectionToken('angularfire2.analytics.config');
34const APP_NAME_KEY = 'app_name';
35const APP_VERSION_KEY = 'app_version';
36const DEBUG_MODE_KEY = 'debug_mode';
37const GTAG_CONFIG_COMMAND = 'config';
38const GTAG_FUNCTION_NAME = 'gtag'; // TODO rename these
39const DATA_LAYER_NAME = 'dataLayer';
40const SEND_TO_KEY = 'send_to';
41class AngularFireAnalytics {
42 constructor(app, analyticsCollectionEnabled, providedAppVersion, providedAppName, debugModeEnabled, providedConfig,
43 // tslint:disable-next-line:ban-types
44 platformId, zone, schedulers) {
45 this.analyticsInitialized = new Promise(() => { });
46 if (isPlatformBrowser(platformId)) {
47 window[DATA_LAYER_NAME] = window[DATA_LAYER_NAME] || [];
48 // It turns out we can't rely on the measurementId in the Firebase config JSON
49 // this identifier is not stable. firebase/analytics does a call to get a fresh value
50 // falling back on the one in the config. Rather than do that ourselves we should listen
51 // on our gtag function for a analytics config command
52 // e.g, ['config', measurementId, { origin: 'firebase', firebase_id }]
53 const parseMeasurementId = (...args) => {
54 if (args[0] === 'config' && args[2].origin === 'firebase') {
55 this.measurementId = args[1];
56 return true;
57 }
58 else {
59 return false;
60 }
61 };
62 const patchGtag = (fn) => {
63 window[GTAG_FUNCTION_NAME] = (...args) => {
64 if (fn) {
65 fn(...args);
66 }
67 // Inject app_name and app_version into events
68 // TODO(jamesdaniels): I'm doing this as documented but it's still not
69 // showing up in the console. Investigate. Guessing it's just part of the
70 // whole GA4 transition mess.
71 if (args[0] === 'event' && args[2][SEND_TO_KEY] === this.measurementId) {
72 if (providedAppName) {
73 args[2][APP_NAME_KEY] = providedAppName;
74 }
75 if (providedAppVersion) {
76 args[2][APP_VERSION_KEY] = providedAppVersion;
77 }
78 }
79 if (debugModeEnabled && typeof console !== 'undefined') {
80 // tslint:disable-next-line:no-console
81 console.info(...args);
82 }
83 /**
84 * According to the gtag documentation, this function that defines a custom data layer cannot be
85 * an arrow function because 'arguments' is not an array. It is actually an object that behaves
86 * like an array and contains more information then just indexes. Transforming this into arrow function
87 * caused issue #2505 where analytics no longer sent any data.
88 */
89 // tslint:disable-next-line: only-arrow-functions
90 (function (..._args) {
91 window[DATA_LAYER_NAME].push(arguments);
92 })(...args);
93 };
94 };
95 // Unclear if we still need to but I was running into config/events I passed
96 // to gtag before ['js' timestamp] weren't getting parsed, so let's make a promise
97 // that resolves when firebase/analytics has configured gtag.js that we wait on
98 // before sending anything
99 const firebaseAnalyticsAlreadyInitialized = window[DATA_LAYER_NAME].some(parseMeasurementId);
100 if (firebaseAnalyticsAlreadyInitialized) {
101 this.analyticsInitialized = Promise.resolve();
102 patchGtag();
103 }
104 else {
105 this.analyticsInitialized = new Promise(resolve => {
106 patchGtag((...args) => {
107 if (parseMeasurementId(...args)) {
108 resolve();
109 }
110 });
111 });
112 }
113 if (providedConfig) {
114 this.updateConfig(providedConfig);
115 }
116 if (debugModeEnabled) {
117 this.updateConfig({ [DEBUG_MODE_KEY]: 1 });
118 }
119 }
120 else {
121 this.analyticsInitialized = Promise.resolve();
122 }
123 const analytics = of(undefined).pipe(observeOn(schedulers.outsideAngular), switchMap(isSupported), switchMap(supported => supported ? zone.runOutsideAngular(() => import('firebase/compat/analytics')) : EMPTY), map(() => {
124 return ɵcacheInstance(`analytics`, 'AngularFireAnalytics', app.name, () => {
125 const analytics = app.analytics();
126 if (analyticsCollectionEnabled === false) {
127 analytics.setAnalyticsCollectionEnabled(false);
128 }
129 return analytics;
130 }, [app, analyticsCollectionEnabled, providedConfig, debugModeEnabled]);
131 }), shareReplay({ bufferSize: 1, refCount: false }));
132 return ɵlazySDKProxy(this, analytics, zone);
133 }
134 updateConfig(config) {
135 return __awaiter(this, void 0, void 0, function* () {
136 yield this.analyticsInitialized;
137 window[GTAG_FUNCTION_NAME](GTAG_CONFIG_COMMAND, this.measurementId, Object.assign(Object.assign({}, config), { update: true }));
138 });
139 }
140}
141AngularFireAnalytics.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireAnalytics, deps: [{ token: i1.FirebaseApp }, { token: COLLECTION_ENABLED, optional: true }, { token: APP_VERSION, optional: true }, { token: APP_NAME, optional: true }, { token: DEBUG_MODE, optional: true }, { token: CONFIG, optional: true }, { token: PLATFORM_ID }, { token: i0.NgZone }, { token: i2.ɵAngularFireSchedulers }], target: i0.ɵɵFactoryTarget.Injectable });
142AngularFireAnalytics.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireAnalytics, providedIn: 'any' });
143i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireAnalytics, decorators: [{
144 type: Injectable,
145 args: [{
146 providedIn: 'any'
147 }]
148 }], ctorParameters: function () { return [{ type: i1.FirebaseApp }, { type: undefined, decorators: [{
149 type: Optional
150 }, {
151 type: Inject,
152 args: [COLLECTION_ENABLED]
153 }] }, { type: undefined, decorators: [{
154 type: Optional
155 }, {
156 type: Inject,
157 args: [APP_VERSION]
158 }] }, { type: undefined, decorators: [{
159 type: Optional
160 }, {
161 type: Inject,
162 args: [APP_NAME]
163 }] }, { type: undefined, decorators: [{
164 type: Optional
165 }, {
166 type: Inject,
167 args: [DEBUG_MODE]
168 }] }, { type: undefined, decorators: [{
169 type: Optional
170 }, {
171 type: Inject,
172 args: [CONFIG]
173 }] }, { type: Object, decorators: [{
174 type: Inject,
175 args: [PLATFORM_ID]
176 }] }, { type: i0.NgZone }, { type: i2.ɵAngularFireSchedulers }]; } });
177ɵapplyMixins(AngularFireAnalytics, [proxyPolyfillCompat]);
178
179class UserTrackingService {
180 // TODO a user properties injector
181 constructor(analytics,
182 // tslint:disable-next-line:ban-types
183 platformId, auth, zone) {
184 this.disposables = [];
185 firebase.registerVersion('angularfire', VERSION.full, 'compat-user-tracking');
186 if (!isPlatformServer(platformId)) {
187 let resolveInitialized;
188 this.initialized = zone.runOutsideAngular(() => new Promise(resolve => resolveInitialized = resolve));
189 this.disposables = [
190 auth.authState.subscribe(user => {
191 analytics.setUserId(user === null || user === void 0 ? void 0 : user.uid);
192 resolveInitialized();
193 }),
194 auth.credential.subscribe(credential => {
195 if (credential) {
196 const method = credential.user.isAnonymous ? 'anonymous' : credential.additionalUserInfo.providerId;
197 if (credential.additionalUserInfo.isNewUser) {
198 analytics.logEvent('sign_up', { method });
199 }
200 analytics.logEvent('login', { method });
201 }
202 })
203 ];
204 }
205 else {
206 this.initialized = Promise.resolve();
207 }
208 }
209 ngOnDestroy() {
210 this.disposables.forEach(it => it.unsubscribe());
211 }
212}
213UserTrackingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: UserTrackingService, deps: [{ token: AngularFireAnalytics }, { token: PLATFORM_ID }, { token: i2$1.AngularFireAuth }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
214UserTrackingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: UserTrackingService });
215i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: UserTrackingService, decorators: [{
216 type: Injectable
217 }], ctorParameters: function () { return [{ type: AngularFireAnalytics }, { type: Object, decorators: [{
218 type: Inject,
219 args: [PLATFORM_ID]
220 }] }, { type: i2$1.AngularFireAuth }, { type: i0.NgZone }]; } });
221
222const SCREEN_VIEW_EVENT = 'screen_view';
223class ScreenTrackingService {
224 constructor(analytics, router, title, componentFactoryResolver, zone, userTrackingService) {
225 firebase.registerVersion('angularfire', VERSION.full, 'compat-screen-tracking');
226 if (!router || !analytics) {
227 return this;
228 }
229 zone.runOutsideAngular(() => {
230 this.disposable = ɵscreenViewEvent(router, title, componentFactoryResolver).pipe(switchMap((params) => __awaiter(this, void 0, void 0, function* () {
231 if (userTrackingService) {
232 yield userTrackingService.initialized;
233 }
234 return yield analytics.logEvent(SCREEN_VIEW_EVENT, params);
235 }))).subscribe();
236 });
237 }
238 ngOnDestroy() {
239 if (this.disposable) {
240 this.disposable.unsubscribe();
241 }
242 }
243}
244ScreenTrackingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: ScreenTrackingService, deps: [{ token: AngularFireAnalytics }, { token: i2$2.Router, optional: true }, { token: i3.Title, optional: true }, { token: i0.ComponentFactoryResolver }, { token: i0.NgZone }, { token: UserTrackingService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
245ScreenTrackingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: ScreenTrackingService });
246i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: ScreenTrackingService, decorators: [{
247 type: Injectable
248 }], ctorParameters: function () { return [{ type: AngularFireAnalytics }, { type: i2$2.Router, decorators: [{
249 type: Optional
250 }] }, { type: i3.Title, decorators: [{
251 type: Optional
252 }] }, { type: i0.ComponentFactoryResolver }, { type: i0.NgZone }, { type: UserTrackingService, decorators: [{
253 type: Optional
254 }] }]; } });
255
256class AngularFireAnalyticsModule {
257 constructor(analytics, screenTracking, userTracking) {
258 firebase.registerVersion('angularfire', VERSION.full, 'analytics-compat');
259 // calling anything on analytics will eagerly load the SDK
260 // tslint:disable-next-line:no-unused-expression
261 analytics.app.then(() => { });
262 }
263}
264AngularFireAnalyticsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireAnalyticsModule, deps: [{ token: AngularFireAnalytics }, { token: ScreenTrackingService, optional: true }, { token: UserTrackingService, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
265AngularFireAnalyticsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireAnalyticsModule });
266AngularFireAnalyticsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireAnalyticsModule, providers: [AngularFireAnalytics] });
267i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireAnalyticsModule, decorators: [{
268 type: NgModule,
269 args: [{
270 providers: [AngularFireAnalytics]
271 }]
272 }], ctorParameters: function () { return [{ type: AngularFireAnalytics }, { type: ScreenTrackingService, decorators: [{
273 type: Optional
274 }] }, { type: UserTrackingService, decorators: [{
275 type: Optional
276 }] }]; } });
277
278/**
279 * Generated bundle index. Do not edit.
280 */
281
282export { APP_NAME, APP_VERSION, AngularFireAnalytics, AngularFireAnalyticsModule, COLLECTION_ENABLED, CONFIG, DEBUG_MODE, ScreenTrackingService, UserTrackingService };
283//# sourceMappingURL=angular-fire-compat-analytics.js.map