Skip to content

Commit 69e2ee0

Browse files
authored
Add function setDefaultEventParameters() to set data that will be logged on every analytics SDK event (#6367)
* Add initial design * Update API reports * Update to checking for wrappedGtagFunction * Add initialize test for gtag set * Add test for _setDefaultEventParametersForInit() * Update formating * Add tests for setDefaultEventParameters * remove extra new line * move defaultEventParametersForInit and funcs to functions file * Add changeset * Resolve PR comments * Capitalize Analytics in changeset * Remove quotes around Analytics in changeset * Update setDefaultEventParameters doc string
1 parent d3336a9 commit 69e2ee0

File tree

8 files changed

+131
-4
lines changed

8 files changed

+131
-4
lines changed

.changeset/silly-panthers-mix.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@firebase/analytics': minor
3+
---
4+
5+
Add function `setDefaultEventParameters()` to set data that will be logged on every Analytics SDK event

common/api-review/analytics.api.md

+3
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ export function setAnalyticsCollectionEnabled(analyticsInstance: Analytics, enab
391391
// @public @deprecated
392392
export function setCurrentScreen(analyticsInstance: Analytics, screenName: string, options?: AnalyticsCallOptions): void;
393393

394+
// @public
395+
export function setDefaultEventParameters(customParams: CustomParams): void;
396+
394397
// @public
395398
export function settings(options: SettingsOptions): void;
396399

packages/analytics/src/api.test.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,22 @@ import { expect } from 'chai';
1919
import { SinonStub, stub } from 'sinon';
2020
import '../testing/setup';
2121
import { getFullApp } from '../testing/get-fake-firebase-services';
22-
import { getAnalytics, initializeAnalytics } from './api';
22+
import {
23+
getAnalytics,
24+
initializeAnalytics,
25+
setDefaultEventParameters
26+
} from './api';
2327
import { FirebaseApp, deleteApp } from '@firebase/app';
2428
import { AnalyticsError } from './errors';
2529
import * as init from './initialize-analytics';
2630
const fakeAppParams = { appId: 'abcdefgh12345:23405', apiKey: 'AAbbCCdd12345' };
31+
import * as factory from './factory';
32+
import { defaultEventParametersForInit } from './functions';
2733

2834
describe('FirebaseAnalytics API tests', () => {
2935
let initStub: SinonStub = stub();
3036
let app: FirebaseApp;
37+
const wrappedGtag: SinonStub = stub();
3138

3239
beforeEach(() => {
3340
initStub = stub(init, '_initializeAnalytics').resolves(
@@ -94,4 +101,26 @@ describe('FirebaseAnalytics API tests', () => {
94101
const analyticsInstance = initializeAnalytics(app);
95102
expect(getAnalytics(app)).to.equal(analyticsInstance);
96103
});
104+
it('setDefaultEventParameters() updates defaultEventParametersForInit if gtag does not exist ', () => {
105+
const eventParametersForInit = {
106+
'github_user': 'dwyfrequency',
107+
'company': 'google'
108+
};
109+
app = getFullApp(fakeAppParams);
110+
setDefaultEventParameters(eventParametersForInit);
111+
expect(defaultEventParametersForInit).to.deep.equal(eventParametersForInit);
112+
});
113+
it('setDefaultEventParameters() calls gtag set if wrappedGtagFunction exists', () => {
114+
const eventParametersForInit = {
115+
'github_user': 'dwyfrequency',
116+
'company': 'google'
117+
};
118+
stub(factory, 'wrappedGtagFunction').get(() => wrappedGtag);
119+
app = getFullApp(fakeAppParams);
120+
setDefaultEventParameters(eventParametersForInit);
121+
expect(wrappedGtag).to.have.been.calledWithExactly(
122+
'set',
123+
eventParametersForInit
124+
);
125+
});
97126
});

packages/analytics/src/api.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {
3535
getModularInstance,
3636
deepEqual
3737
} from '@firebase/util';
38-
import { ANALYTICS_TYPE } from './constants';
38+
import { ANALYTICS_TYPE, GtagCommand } from './constants';
3939
import {
4040
AnalyticsService,
4141
initializationPromisesMap,
@@ -47,7 +47,8 @@ import {
4747
setCurrentScreen as internalSetCurrentScreen,
4848
setUserId as internalSetUserId,
4949
setUserProperties as internalSetUserProperties,
50-
setAnalyticsCollectionEnabled as internalSetAnalyticsCollectionEnabled
50+
setAnalyticsCollectionEnabled as internalSetAnalyticsCollectionEnabled,
51+
_setDefaultEventParametersForInit
5152
} from './functions';
5253
import { ERROR_FACTORY, AnalyticsError } from './errors';
5354

@@ -224,6 +225,23 @@ export function setAnalyticsCollectionEnabled(
224225
enabled
225226
).catch(e => logger.error(e));
226227
}
228+
229+
/**
230+
* Adds data that will be set on every event logged from the SDK, including automatic ones.
231+
* With gtag's "set" command, the values passed persist on the current page and are passed with
232+
* all subsequent events.
233+
* @public
234+
* @param customParams Any custom params the user may pass to gtag.js.
235+
*/
236+
export function setDefaultEventParameters(customParams: CustomParams): void {
237+
// Check if reference to existing gtag function on window object exists
238+
if (wrappedGtagFunction) {
239+
wrappedGtagFunction(GtagCommand.SET, customParams);
240+
} else {
241+
_setDefaultEventParametersForInit(customParams);
242+
}
243+
}
244+
227245
/**
228246
* Sends a Google Analytics event with given `eventParams`. This method
229247
* automatically associates this logged event with this Firebase web

packages/analytics/src/functions.test.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ import {
2323
logEvent,
2424
setUserId,
2525
setUserProperties,
26-
setAnalyticsCollectionEnabled
26+
setAnalyticsCollectionEnabled,
27+
defaultEventParametersForInit,
28+
_setDefaultEventParametersForInit
2729
} from './functions';
2830
import { GtagCommand } from './constants';
2931

@@ -170,4 +172,24 @@ describe('FirebaseAnalytics methods', () => {
170172
expect(window[`ga-disable-${fakeMeasurementId}`]).to.be.true;
171173
delete window[`ga-disable-${fakeMeasurementId}`];
172174
});
175+
it('_setDefaultEventParametersForInit() stores individual params correctly', async () => {
176+
const eventParametersForInit = {
177+
'github_user': 'dwyfrequency',
178+
'company': 'google'
179+
};
180+
_setDefaultEventParametersForInit(eventParametersForInit);
181+
expect(defaultEventParametersForInit).to.deep.equal(eventParametersForInit);
182+
});
183+
it('_setDefaultEventParametersForInit() replaces previous params with new params', async () => {
184+
const eventParametersForInit = {
185+
'github_user': 'dwyfrequency',
186+
'company': 'google'
187+
};
188+
const additionalParams = { 'food': 'sushi' };
189+
_setDefaultEventParametersForInit(eventParametersForInit);
190+
_setDefaultEventParametersForInit(additionalParams);
191+
expect(defaultEventParametersForInit).to.deep.equal({
192+
...additionalParams
193+
});
194+
});
173195
});

packages/analytics/src/functions.ts

+18
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ import {
2323
} from './public-types';
2424
import { Gtag } from './types';
2525
import { GtagCommand } from './constants';
26+
27+
/**
28+
* Event parameters to set on 'gtag' during initialization.
29+
*/
30+
export let defaultEventParametersForInit: CustomParams | undefined;
31+
2632
/**
2733
* Logs an analytics event through the Firebase SDK.
2834
*
@@ -142,3 +148,15 @@ export async function setAnalyticsCollectionEnabled(
142148
const measurementId = await initializationPromise;
143149
window[`ga-disable-${measurementId}`] = !enabled;
144150
}
151+
152+
/**
153+
* Sets the variable `defaultEventParametersForInit` for use in the initialization of
154+
* analytics.
155+
*
156+
* @param customParams Any custom params the user may pass to gtag.js.
157+
*/
158+
export function _setDefaultEventParametersForInit(
159+
customParams?: CustomParams
160+
): void {
161+
defaultEventParametersForInit = customParams;
162+
}

packages/analytics/src/initialize-analytics.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import { FirebaseApp } from '@firebase/app';
2929
import { Deferred } from '@firebase/util';
3030
import { _FirebaseInstallationsInternal } from '@firebase/installations';
3131
import { removeGtagScript } from '../testing/gtag-script-util';
32+
import { setDefaultEventParameters } from './api';
33+
import { defaultEventParametersForInit } from './functions';
3234

3335
const fakeMeasurementId = 'abcd-efgh-ijkl';
3436
const fakeFid = 'fid-1234-zyxw';
@@ -97,6 +99,25 @@ describe('initializeAnalytics()', () => {
9799
'send_page_view': false
98100
});
99101
});
102+
it('calls gtag set if there are default event parameters', async () => {
103+
stubFetch();
104+
const eventParametersForInit = {
105+
'github_user': 'dwyfrequency',
106+
'company': 'google'
107+
};
108+
setDefaultEventParameters(eventParametersForInit);
109+
await _initializeAnalytics(
110+
app,
111+
dynamicPromisesList,
112+
measurementIdToAppId,
113+
fakeInstallations,
114+
gtagStub,
115+
'dataLayer'
116+
);
117+
expect(gtagStub).to.be.calledWith(GtagCommand.SET, eventParametersForInit);
118+
// defaultEventParametersForInit is reset after initialization.
119+
expect(defaultEventParametersForInit).to.equal(undefined);
120+
});
100121
it('puts dynamic fetch promise into dynamic promises list', async () => {
101122
stubFetch();
102123
await _initializeAnalytics(

packages/analytics/src/initialize-analytics.ts

+11
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ import {
2828
import { ERROR_FACTORY, AnalyticsError } from './errors';
2929
import { findGtagScriptOnPage, insertScriptTag } from './helpers';
3030
import { AnalyticsSettings } from './public-types';
31+
import {
32+
defaultEventParametersForInit,
33+
_setDefaultEventParametersForInit
34+
} from './functions';
3135

3236
async function validateIndexedDB(): Promise<boolean> {
3337
if (!isIndexedDBAvailable()) {
@@ -140,5 +144,12 @@ export async function _initializeAnalytics(
140144
// Note: This will trigger a page_view event unless 'send_page_view' is set to false in
141145
// `configProperties`.
142146
gtagCore(GtagCommand.CONFIG, dynamicConfig.measurementId, configProperties);
147+
148+
// Detects if there is data that will be set on every event logged from the SDK.
149+
if (defaultEventParametersForInit) {
150+
gtagCore(GtagCommand.SET, defaultEventParametersForInit);
151+
_setDefaultEventParametersForInit(undefined);
152+
}
153+
143154
return dynamicConfig.measurementId;
144155
}

0 commit comments

Comments
 (0)