Skip to content

Commit 0e26c15

Browse files
committed
Implement using provider.initialize()
1 parent 83092d4 commit 0e26c15

File tree

8 files changed

+45
-62
lines changed

8 files changed

+45
-62
lines changed

common/api-review/analytics-exp.api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export interface AnalyticsCallOptions {
1818

1919
// @public
2020
export interface AnalyticsOptions {
21-
config: GtagConfigParams | EventParams;
21+
config?: GtagConfigParams | EventParams;
2222
}
2323

2424
// @public

packages-exp/analytics-exp/src/api.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import { ANALYTICS_TYPE } from './constants';
3838
import {
3939
AnalyticsService,
4040
initializationPromisesMap,
41-
_initializeAnalyticsForApp,
4241
wrappedGtagFunction
4342
} from './factory';
4443
import { logger } from './logger';
@@ -90,7 +89,7 @@ export function getAnalytics(app: FirebaseApp = getApp()): Analytics {
9089
*/
9190
export function initializeAnalytics(
9291
app: FirebaseApp,
93-
options?: AnalyticsOptions
92+
options: AnalyticsOptions = {}
9493
): Analytics {
9594
// Dependencies
9695
const analyticsProvider: Provider<'analytics-exp'> = _getProvider(
@@ -100,13 +99,7 @@ export function initializeAnalytics(
10099
if (analyticsProvider.isInitialized()) {
101100
throw ERROR_FACTORY.create(AnalyticsError.ALREADY_INITIALIZED);
102101
}
103-
const analyticsInstance = analyticsProvider.getImmediate();
104-
// do init settings stuff here
105-
const installations = _getProvider(
106-
app,
107-
'installations-exp-internal'
108-
).getImmediate();
109-
_initializeAnalyticsForApp(app, installations, options);
102+
const analyticsInstance = analyticsProvider.initialize({ options });
110103
return analyticsInstance;
111104
}
112105

packages-exp/analytics-exp/src/factory.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { getOrCreateDataLayer, wrapOrCreateGtag } from './helpers';
2121
import { AnalyticsError, ERROR_FACTORY } from './errors';
2222
import { _FirebaseInstallationsInternal } from '@firebase/installations-exp';
2323
import { areCookiesEnabled, isBrowserExtension } from '@firebase/util';
24-
import { _initializeAnalytics } from './initialize-analytics';
24+
import { initializeAnalytics } from './initialize-analytics';
2525
import { logger } from './logger';
2626
import { FirebaseApp, _FirebaseService } from '@firebase/app-exp';
2727

@@ -136,7 +136,7 @@ export function getGlobalVars(): {
136136
*/
137137
export function settings(options: SettingsOptions): void {
138138
if (globalInitDone) {
139-
throw ERROR_FACTORY.create(AnalyticsError.ALREADY_INITIALIZED_SETTINGS);
139+
throw ERROR_FACTORY.create(AnalyticsError.ALREADY_INITIALIZED);
140140
}
141141
if (options.dataLayerName) {
142142
dataLayerName = options.dataLayerName;
@@ -174,7 +174,11 @@ function warnOnBrowserContextMismatch(): void {
174174
* Analytics instance factory.
175175
* @internal
176176
*/
177-
export function factory(app: FirebaseApp): AnalyticsService {
177+
export function factory(
178+
app: FirebaseApp,
179+
installations: _FirebaseInstallationsInternal,
180+
options?: AnalyticsOptions
181+
): AnalyticsService {
178182
warnOnBrowserContextMismatch();
179183
const appId = app.options.appId;
180184
if (!appId) {
@@ -215,23 +219,9 @@ export function factory(app: FirebaseApp): AnalyticsService {
215219

216220
globalInitDone = true;
217221
}
218-
219-
const analyticsInstance: AnalyticsService = new AnalyticsService(app);
220-
return analyticsInstance;
221-
}
222-
223-
/**
224-
* Starts async initializations for this app.
225-
*/
226-
export function _initializeAnalyticsForApp(
227-
app: FirebaseApp,
228-
installations: _FirebaseInstallationsInternal,
229-
options?: AnalyticsOptions
230-
): void {
231222
// Async but non-blocking.
232223
// This map reflects the completion state of all promises for each appId.
233-
// Factory will have thrown if options has no appId.
234-
initializationPromisesMap[app.options.appId!] = _initializeAnalytics(
224+
initializationPromisesMap[appId] = initializeAnalytics(
235225
app,
236226
dynamicConfigPromisesList,
237227
measurementIdToAppId,
@@ -240,4 +230,8 @@ export function _initializeAnalyticsForApp(
240230
dataLayerName,
241231
options
242232
);
233+
234+
const analyticsInstance: AnalyticsService = new AnalyticsService(app);
235+
236+
return analyticsInstance;
243237
}

packages-exp/analytics-exp/src/index.test.ts

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ import {
3434
AnalyticsService,
3535
getGlobalVars,
3636
resetGlobalVars,
37-
factory as analyticsFactory,
38-
_initializeAnalyticsForApp
37+
factory as analyticsFactory
3938
} from './factory';
4039
import { _FirebaseInstallationsInternal } from '@firebase/installations-exp';
4140

@@ -90,11 +89,15 @@ describe('FirebaseAnalytics instance tests', () => {
9089

9190
it('Throws if no appId in config', () => {
9291
const app = getFakeApp({ apiKey: fakeAppParams.apiKey });
93-
expect(() => analyticsFactory(app)).to.throw(AnalyticsError.NO_APP_ID);
92+
expect(() => analyticsFactory(app, fakeInstallations)).to.throw(
93+
AnalyticsError.NO_APP_ID
94+
);
9495
});
9596
it('Throws if no apiKey or measurementId in config', () => {
9697
const app = getFakeApp({ appId: fakeAppParams.appId });
97-
expect(() => analyticsFactory(app)).to.throw(AnalyticsError.NO_API_KEY);
98+
expect(() => analyticsFactory(app, fakeInstallations)).to.throw(
99+
AnalyticsError.NO_API_KEY
100+
);
98101
});
99102
it('Warns if config has no apiKey but does have a measurementId', async () => {
100103
// Since this is a warning and doesn't block the rest of initialization
@@ -107,8 +110,7 @@ describe('FirebaseAnalytics instance tests', () => {
107110
measurementId: fakeMeasurementId
108111
});
109112
stubIdbOpen();
110-
analyticsFactory(app);
111-
_initializeAnalyticsForApp(app, fakeInstallations);
113+
analyticsFactory(app, fakeInstallations);
112114
// Successfully resolves fake IDB open request.
113115
fakeRequest.onsuccess();
114116
// Lets async IDB validation process complete.
@@ -126,7 +128,7 @@ describe('FirebaseAnalytics instance tests', () => {
126128
it('Throws if creating an instance with already-used appId', () => {
127129
const app = getFakeApp(fakeAppParams);
128130
resetGlobalVars(false, { [fakeAppParams.appId]: Promise.resolve() });
129-
expect(() => analyticsFactory(app)).to.throw(
131+
expect(() => analyticsFactory(app, fakeInstallations)).to.throw(
130132
AnalyticsError.ALREADY_EXISTS
131133
);
132134
});
@@ -147,8 +149,7 @@ describe('FirebaseAnalytics instance tests', () => {
147149
window['dataLayer'] = [];
148150
stubFetch(200, { measurementId: fakeMeasurementId });
149151
stubIdbOpen();
150-
analyticsInstance = analyticsFactory(app);
151-
_initializeAnalyticsForApp(app, fakeInstallations);
152+
analyticsInstance = analyticsFactory(app, fakeInstallations);
152153
// Successfully resolves fake IDB open request.
153154
fakeRequest.onsuccess();
154155
});
@@ -222,8 +223,7 @@ describe('FirebaseAnalytics instance tests', () => {
222223
});
223224
it('Warns on initialization if cookies not available', async () => {
224225
cookieStub = stub(navigator, 'cookieEnabled').value(false);
225-
analyticsInstance = analyticsFactory(app);
226-
_initializeAnalyticsForApp(app, fakeInstallations);
226+
analyticsInstance = analyticsFactory(app, fakeInstallations);
227227
// Successfully resolves fake IDB open request.
228228
fakeRequest.onsuccess();
229229
expect(warnStub.args[0][1]).to.include(
@@ -234,8 +234,7 @@ describe('FirebaseAnalytics instance tests', () => {
234234
});
235235
it('Warns on initialization if in browser extension', async () => {
236236
window.chrome = { runtime: { id: 'blah' } };
237-
analyticsInstance = analyticsFactory(app);
238-
_initializeAnalyticsForApp(app, fakeInstallations);
237+
analyticsInstance = analyticsFactory(app, fakeInstallations);
239238
// Successfully resolves fake IDB open request.
240239
fakeRequest.onsuccess();
241240
expect(warnStub.args[0][1]).to.include(
@@ -246,8 +245,7 @@ describe('FirebaseAnalytics instance tests', () => {
246245
});
247246
it('Warns on logEvent if indexedDB API not available', async () => {
248247
const idbStub = stub(window, 'indexedDB').value(undefined);
249-
analyticsInstance = analyticsFactory(app);
250-
_initializeAnalyticsForApp(app, fakeInstallations);
248+
analyticsInstance = analyticsFactory(app, fakeInstallations);
251249
logEvent(analyticsInstance, 'add_payment_info', {
252250
currency: 'USD'
253251
});
@@ -267,8 +265,7 @@ describe('FirebaseAnalytics instance tests', () => {
267265
it('Warns on logEvent if indexedDB.open() not allowed', async () => {
268266
idbOpenStub.restore();
269267
idbOpenStub = stub(indexedDB, 'open').throws('idb open error test');
270-
analyticsInstance = analyticsFactory(app);
271-
_initializeAnalyticsForApp(app, fakeInstallations);
268+
analyticsInstance = analyticsFactory(app, fakeInstallations);
272269
logEvent(analyticsInstance, 'add_payment_info', {
273270
currency: 'USD'
274271
});
@@ -306,8 +303,7 @@ describe('FirebaseAnalytics instance tests', () => {
306303
});
307304
stubIdbOpen();
308305
stubFetch(200, { measurementId: fakeMeasurementId });
309-
analyticsInstance = analyticsFactory(app);
310-
_initializeAnalyticsForApp(app, fakeInstallations);
306+
analyticsInstance = analyticsFactory(app, fakeInstallations);
311307
// Successfully resolves fake IDB open request.
312308
fakeRequest.onsuccess();
313309
});
@@ -353,8 +349,7 @@ describe('FirebaseAnalytics instance tests', () => {
353349
fakeInstallations = getFakeInstallations();
354350
stubFetch(200, {});
355351
stubIdbOpen();
356-
analyticsInstance = analyticsFactory(app);
357-
_initializeAnalyticsForApp(app, fakeInstallations);
352+
analyticsInstance = analyticsFactory(app, fakeInstallations);
358353

359354
const { initializationPromisesMap } = getGlobalVars();
360355
// Successfully resolves fake IDB open request.

packages-exp/analytics-exp/src/index.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ import { ANALYTICS_TYPE } from './constants';
2828
import {
2929
Component,
3030
ComponentType,
31-
ComponentContainer
31+
ComponentContainer,
32+
InstanceFactoryOptions
3233
} from '@firebase/component';
3334
import { ERROR_FACTORY, AnalyticsError } from './errors';
3435
import { logEvent } from './api';
@@ -46,11 +47,14 @@ function registerAnalytics(): void {
4647
_registerComponent(
4748
new Component(
4849
ANALYTICS_TYPE,
49-
container => {
50+
(container, { options: analyticsOptions }: InstanceFactoryOptions) => {
5051
// getImmediate for FirebaseApp will always succeed
5152
const app = container.getProvider('app-exp').getImmediate();
53+
const installations = container
54+
.getProvider('installations-exp-internal')
55+
.getImmediate();
5256

53-
return factory(app);
57+
return factory(app, installations, analyticsOptions);
5458
},
5559
ComponentType.PUBLIC
5660
)
@@ -65,8 +69,6 @@ function registerAnalytics(): void {
6569
function internalFactory(
6670
container: ComponentContainer
6771
): FirebaseAnalyticsInternal {
68-
//TODO: initialization fetches aren't in factory anymore so it might need to be
69-
// called here.
7072
try {
7173
const analytics = container.getProvider(ANALYTICS_TYPE).getImmediate();
7274
return {

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import { expect } from 'chai';
1919
import { SinonStub, stub } from 'sinon';
2020
import '../testing/setup';
21-
import { _initializeAnalytics } from './initialize-analytics';
21+
import { initializeAnalytics } from './initialize-analytics';
2222
import {
2323
getFakeApp,
2424
getFakeInstallations
@@ -65,7 +65,7 @@ describe('initializeIds()', () => {
6565
});
6666
it('gets FID and measurement ID and calls gtag config with them', async () => {
6767
stubFetch();
68-
await _initializeAnalytics(
68+
await initializeAnalytics(
6969
app,
7070
dynamicPromisesList,
7171
measurementIdToAppId,
@@ -81,7 +81,7 @@ describe('initializeIds()', () => {
8181
});
8282
it('puts dynamic fetch promise into dynamic promises list', async () => {
8383
stubFetch();
84-
await _initializeAnalytics(
84+
await initializeAnalytics(
8585
app,
8686
dynamicPromisesList,
8787
measurementIdToAppId,
@@ -95,7 +95,7 @@ describe('initializeIds()', () => {
9595
});
9696
it('puts dynamically fetched measurementId into lookup table', async () => {
9797
stubFetch();
98-
await _initializeAnalytics(
98+
await initializeAnalytics(
9999
app,
100100
dynamicPromisesList,
101101
measurementIdToAppId,
@@ -108,7 +108,7 @@ describe('initializeIds()', () => {
108108
it('warns on local/fetched measurement ID mismatch', async () => {
109109
stubFetch();
110110
const consoleStub = stub(console, 'warn');
111-
await _initializeAnalytics(
111+
await initializeAnalytics(
112112
getFakeApp({ ...fakeAppParams, measurementId: 'old-measurement-id' }),
113113
dynamicPromisesList,
114114
measurementIdToAppId,

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ async function validateIndexedDB(): Promise<boolean> {
6565
*
6666
* @returns Measurement ID.
6767
*/
68-
export async function _initializeAnalytics(
68+
export async function initializeAnalytics(
6969
app: FirebaseApp,
7070
dynamicConfigPromisesList: Array<
7171
Promise<DynamicConfig | MinimalDynamicConfig>
@@ -123,7 +123,6 @@ export async function _initializeAnalytics(
123123
// We keep it together with other initialization logic for better code structure.
124124
// eslint-disable-next-line @typescript-eslint/no-explicit-any
125125
(gtagCore as any)('js', new Date());
126-
127126
// User config added first. We don't want users to accidentally overwrite
128127
// base Firebase config properties.
129128
const configProperties: Record<string, unknown> = options?.config ?? {};

packages-exp/analytics-exp/src/public-types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export interface AnalyticsOptions {
106106
/**
107107
* Params to be passed in the initial gtag config call during analytics initialization.
108108
*/
109-
config: GtagConfigParams | EventParams;
109+
config?: GtagConfigParams | EventParams;
110110
}
111111

112112
/**

0 commit comments

Comments
 (0)