1
- import { Injectable , Inject , Optional , NgZone , InjectionToken } from '@angular/core' ;
1
+ import { Injectable , Inject , Optional , NgZone , InjectionToken , PLATFORM_ID } from '@angular/core' ;
2
2
import { of } from 'rxjs' ;
3
+ import { isPlatformBrowser } from '@angular/common' ;
3
4
import { map , tap , shareReplay , switchMap } from 'rxjs/operators' ;
4
5
import { FirebaseAppConfig , FirebaseOptions , runOutsideAngular , ɵlazySDKProxy , FirebaseAnalytics , FIREBASE_OPTIONS , FIREBASE_APP_NAME , _firebaseAppFactory } from '@angular/fire' ;
5
6
import { analytics , app } from 'firebase' ;
@@ -15,9 +16,8 @@ const APP_VERSION_KEY = 'app_version';
15
16
const DEBUG_MODE_KEY = 'debug_mode' ;
16
17
const ANALYTICS_ID_FIELD = 'measurementId' ;
17
18
const GTAG_CONFIG_COMMAND = 'config' ;
18
-
19
- // TODO can we get this from js sdk?
20
- const GTAG_FUNCTION = 'gtag' ;
19
+ const GTAG_FUNCTION_NAME = 'gtag' ;
20
+ const DATA_LAYER_NAME = 'dataLayer' ;
21
21
22
22
// SEMVER: once we move to Typescript 3.6 use `PromiseProxy<analytics.Analytics>`
23
23
type AnalyticsProxy = {
@@ -36,17 +36,42 @@ export interface AngularFireAnalytics extends AnalyticsProxy {};
36
36
@Injectable ( )
37
37
export class AngularFireAnalytics {
38
38
39
- public updateConfig : ( options : { [ key :string ] : any } ) => void ;
39
+ private gtag : ( ...args : any [ ] ) => { } ;
40
+ private analyticsInitialized : Promise < void > ;
41
+
42
+ async updateConfig ( config : { [ key :string ] : any } ) {
43
+ await this . analyticsInitialized ;
44
+ this . gtag ( GTAG_CONFIG_COMMAND , this . options [ ANALYTICS_ID_FIELD ] , { ...config , update : true } ) ;
45
+ } ;
40
46
41
47
constructor (
42
- @Inject ( FIREBASE_OPTIONS ) options :FirebaseOptions ,
48
+ @Inject ( FIREBASE_OPTIONS ) private options :FirebaseOptions ,
43
49
@Optional ( ) @Inject ( FIREBASE_APP_NAME ) nameOrConfig :string | FirebaseAppConfig | null | undefined ,
44
50
@Optional ( ) @Inject ( ANALYTICS_COLLECTION_ENABLED ) analyticsCollectionEnabled :boolean | null ,
45
51
@Optional ( ) @Inject ( APP_VERSION ) providedAppVersion :string | null ,
46
52
@Optional ( ) @Inject ( APP_NAME ) providedAppName :string | null ,
47
53
@Optional ( ) @Inject ( DEBUG_MODE ) debugModeEnabled :boolean | null ,
54
+ @Inject ( PLATFORM_ID ) platformId ,
48
55
zone : NgZone
49
56
) {
57
+
58
+ if ( isPlatformBrowser ( platformId ) ) {
59
+ window [ DATA_LAYER_NAME ] = window [ DATA_LAYER_NAME ] || [ ] ;
60
+ this . gtag = window [ GTAG_FUNCTION_NAME ] || function ( ) { window [ DATA_LAYER_NAME ] . push ( arguments ) }
61
+ this . analyticsInitialized = new Promise ( resolve => {
62
+ window [ GTAG_FUNCTION_NAME ] = ( ...args : any [ ] ) => {
63
+ if ( args [ 0 ] == 'js' ) { resolve ( ) }
64
+ this . gtag ( ...args ) ;
65
+ }
66
+ } ) ;
67
+ } else {
68
+ this . analyticsInitialized = Promise . reject ( ) ;
69
+ }
70
+
71
+ if ( providedAppName ) { this . updateConfig ( { [ APP_NAME_KEY ] : providedAppName } ) }
72
+ if ( providedAppVersion ) { this . updateConfig ( { [ APP_VERSION_KEY ] : providedAppVersion } ) }
73
+ if ( debugModeEnabled ) { this . updateConfig ( { [ DEBUG_MODE_KEY ] : 1 } ) }
74
+
50
75
const analytics = of ( undefined ) . pipe (
51
76
// @ts -ignore zapping in the UMD in the build script
52
77
switchMap ( ( ) => zone . runOutsideAngular ( ( ) => import ( 'firebase/analytics' ) ) ) ,
@@ -55,18 +80,11 @@ export class AngularFireAnalytics {
55
80
map ( app => < analytics . Analytics > app . analytics ( ) ) ,
56
81
tap ( analytics => {
57
82
if ( analyticsCollectionEnabled === false ) { analytics . setAnalyticsCollectionEnabled ( false ) }
58
- if ( providedAppName ) { this . updateConfig ( { [ APP_NAME_KEY ] : providedAppName } ) }
59
- if ( providedAppVersion ) { this . updateConfig ( { [ APP_VERSION_KEY ] : providedAppVersion } ) }
60
- if ( debugModeEnabled ) { this . updateConfig ( { [ DEBUG_MODE_KEY ] : 1 } ) }
61
83
} ) ,
62
84
runOutsideAngular ( zone ) ,
63
85
shareReplay ( 1 )
64
86
) ;
65
87
66
- this . updateConfig = ( config : { [ key :string ] : any } ) => analytics . toPromise ( ) . then ( ( ) =>
67
- window [ GTAG_FUNCTION ] ( GTAG_CONFIG_COMMAND , options [ ANALYTICS_ID_FIELD ] , { ...config , update : true } )
68
- ) ;
69
-
70
88
return ɵlazySDKProxy ( this , analytics , zone ) ;
71
89
}
72
90
0 commit comments