11import { Injectable , Inject , Optional , NgZone , InjectionToken } from '@angular/core' ;
2- import { Observable , from } from 'rxjs' ;
3- import { map , tap , filter , withLatestFrom , shareReplay } from 'rxjs/operators' ;
4- import { Router , NavigationEnd , ActivationEnd } from '@angular/router' ;
2+ import { of } from 'rxjs' ;
3+ import { map , tap , shareReplay , switchMap } from 'rxjs/operators' ;
54import { FirebaseAppConfig , FirebaseOptions , runOutsideAngular , _lazySDKProxy , FirebaseAnalytics , FIREBASE_OPTIONS , FIREBASE_APP_NAME , _firebaseAppFactory } from '@angular/fire' ;
65import { analytics , app } from 'firebase' ;
76
8- export const AUTOMATICALLY_SET_CURRENT_SCREEN = new InjectionToken < boolean > ( 'angularfire2.analytics.setCurrentScreen' ) ;
9- export const AUTOMATICALLY_LOG_SCREEN_VIEWS = new InjectionToken < boolean > ( 'angularfire2.analytics.logScreenViews' ) ;
107export const ANALYTICS_COLLECTION_ENABLED = new InjectionToken < boolean > ( 'angularfire2.analytics.analyticsCollectionEnabled' ) ;
11- export const AUTOMATICALLY_TRACK_USER_IDENTIFIER = new InjectionToken < boolean > ( 'angularfire2.analytics.trackUserIdentifier' ) ;
12- export const APP_VERSION = new InjectionToken < string > ( 'angularfire2.analytics.appVersion' ) ;
13- export const APP_NAME = new InjectionToken < string > ( 'angularfire2.analytics.appName' ) ;
14-
15- export const DEFAULT_APP_VERSION = '?' ;
16- export const DEFAULT_APP_NAME = 'Angular App' ;
178
189// SEMVER: once we move to Typescript 3.6 use `PromiseProxy<analytics.Analytics>`
1910type AnalyticsProxy = {
@@ -29,74 +20,30 @@ type AnalyticsProxy = {
2920
3021export interface AngularFireAnalytics extends AnalyticsProxy { } ;
3122
32- @Injectable ( )
23+ @Injectable ( {
24+ providedIn : "root"
25+ } )
3326export class AngularFireAnalytics {
3427
35- /**
36- * Firebase Analytics instance
37- */
38- private readonly analytics$ : Observable < FirebaseAnalytics > ;
39- private get analytics ( ) { return this . analytics$ . toPromise ( ) ; }
40-
4128 constructor (
4229 @Inject ( FIREBASE_OPTIONS ) options :FirebaseOptions ,
4330 @Optional ( ) @Inject ( FIREBASE_APP_NAME ) nameOrConfig :string | FirebaseAppConfig | null | undefined ,
44- @Optional ( ) router :Router ,
45- @Optional ( ) @Inject ( AUTOMATICALLY_SET_CURRENT_SCREEN ) automaticallySetCurrentScreen :boolean | null ,
46- @Optional ( ) @Inject ( AUTOMATICALLY_LOG_SCREEN_VIEWS ) automaticallyLogScreenViews :boolean | null ,
4731 @Optional ( ) @Inject ( ANALYTICS_COLLECTION_ENABLED ) analyticsCollectionEnabled :boolean | null ,
48- @Optional ( ) @Inject ( AUTOMATICALLY_TRACK_USER_IDENTIFIER ) automaticallyTrackUserIdentifier :boolean | null ,
49- @Optional ( ) @Inject ( APP_VERSION ) providedAppVersion :string | null ,
50- @Optional ( ) @Inject ( APP_NAME ) providedAppName :string | null ,
5132 zone : NgZone
5233 ) {
53- // @ts -ignore zapping in the UMD in the build script
54- const requireAnalytics = from ( import ( 'firebase/analytics' ) ) ;
55- const app = _firebaseAppFactory ( options , zone , nameOrConfig ) ;
56-
57- this . analytics$ = requireAnalytics . pipe (
58- map ( ( ) => app . analytics ( ) ) ,
34+ const analytics = of ( undefined ) . pipe (
35+ // @ts -ignore zapping in the UMD in the build script
36+ switchMap ( ( ) => zone . runOutsideAngular ( ( ) => import ( 'firebase/analytics' ) ) ) ,
37+ map ( ( ) => _firebaseAppFactory ( options , zone , nameOrConfig ) ) ,
38+ map ( app => app . analytics ( ) ) ,
5939 tap ( analytics => {
6040 if ( analyticsCollectionEnabled === false ) { analytics . setAnalyticsCollectionEnabled ( false ) }
6141 } ) ,
6242 runOutsideAngular ( zone ) ,
6343 shareReplay ( 1 )
6444 ) ;
6545
66- if ( router && ( automaticallySetCurrentScreen !== false || automaticallyLogScreenViews !== false ) ) {
67- const app_name = providedAppName || DEFAULT_APP_NAME ;
68- const app_version = providedAppVersion || DEFAULT_APP_VERSION ;
69- const activationEndEvents = router . events . pipe ( filter < ActivationEnd > ( e => e instanceof ActivationEnd ) ) ;
70- const navigationEndEvents = router . events . pipe ( filter < NavigationEnd > ( e => e instanceof NavigationEnd ) ) ;
71- navigationEndEvents . pipe (
72- withLatestFrom ( activationEndEvents , this . analytics$ ) ,
73- tap ( ( [ navigationEnd , activationEnd , analytics ] ) => {
74- const url = navigationEnd . url ;
75- const screen_name = activationEnd . snapshot . routeConfig && activationEnd . snapshot . routeConfig . path || undefined ;
76- const outlet = activationEnd . snapshot . outlet ;
77- if ( automaticallyLogScreenViews !== false ) {
78- analytics . logEvent ( "screen_view" , { app_name, app_version, screen_name, outlet, url } ) ;
79- }
80- if ( automaticallySetCurrentScreen !== false ) {
81- // TODO when is screen_name undefined?
82- analytics . setCurrentScreen ( screen_name || url , { global : outlet == "primary" } ) ;
83- }
84- } ) ,
85- runOutsideAngular ( zone )
86- ) . subscribe ( ) ;
87- }
88-
89- // TODO do something other than just check auth presence, what if it's lazy loaded?
90- if ( app . auth && automaticallyTrackUserIdentifier !== false ) {
91- new Observable < firebase . User | null > ( app . auth ( ) . onAuthStateChanged . bind ( app . auth ( ) ) ) . pipe (
92- withLatestFrom ( this . analytics$ ) ,
93- tap ( ( [ user , analytics ] ) => analytics . setUserId ( user ? user . uid : null ! , { global : true } ) ) ,
94- runOutsideAngular ( zone )
95- ) . subscribe ( )
96- }
97-
98- return _lazySDKProxy ( this , this . analytics , zone ) ;
99-
46+ return _lazySDKProxy ( this , analytics , zone ) ;
10047 }
10148
102- }
49+ }
0 commit comments