From 3a8ed33d0d18762b327bf8c9352a681594218288 Mon Sep 17 00:00:00 2001 From: Anthony Barone Date: Wed, 3 Dec 2025 14:03:05 +0000 Subject: [PATCH] Update FirebaseTelemetry react function to take app --- common/api-review/telemetry-react.api.md | 5 ++- docs-devsite/telemetry_react.md | 14 ++++----- packages/telemetry/src/react/index.test.tsx | 35 +++------------------ packages/telemetry/src/react/index.ts | 27 +++++++++------- 4 files changed, 29 insertions(+), 52 deletions(-) diff --git a/common/api-review/telemetry-react.api.md b/common/api-review/telemetry-react.api.md index dd5a5fe7a16..78571088c5d 100644 --- a/common/api-review/telemetry-react.api.md +++ b/common/api-review/telemetry-react.api.md @@ -5,12 +5,11 @@ ```ts import { FirebaseApp } from '@firebase/app'; -import { FirebaseOptions } from '@firebase/app'; import { LoggerProvider } from '@opentelemetry/sdk-logs'; // @public -export function FirebaseTelemetry({ firebaseOptions, telemetryOptions }: { - firebaseOptions?: FirebaseOptions; +export function FirebaseTelemetry({ firebaseApp, telemetryOptions }: { + firebaseApp: FirebaseApp; telemetryOptions?: TelemetryOptions; }): null; diff --git a/docs-devsite/telemetry_react.md b/docs-devsite/telemetry_react.md index 40d58284958..0425036769e 100644 --- a/docs-devsite/telemetry_react.md +++ b/docs-devsite/telemetry_react.md @@ -15,7 +15,7 @@ https://github.com/firebase/firebase-js-sdk | Function | Description | | --- | --- | -| [FirebaseTelemetry({ firebaseOptions, telemetryOptions })](./telemetry_react.md#firebasetelemetry_f37eb31) | Registers event listeners for uncaught errors.This should be installed near the root of your application. Caught errors, including those implicitly caught by Error Boundaries, will not be captured by this component. | +| [FirebaseTelemetry({ firebaseApp, telemetryOptions })](./telemetry_react.md#firebasetelemetry_10424e8) | Registers event listeners for uncaught errors.This should be installed near the root of your application. Caught errors, including those implicitly caught by Error Boundaries, will not be captured by this component. | ## Interfaces @@ -24,9 +24,9 @@ https://github.com/firebase/firebase-js-sdk | [Telemetry](./telemetry_react.telemetry.md#telemetry_interface) | An instance of the Firebase Telemetry SDK.Do not create this instance directly. Instead, use [getTelemetry()](./telemetry_.md#gettelemetry_448bdc6). | | [TelemetryOptions](./telemetry_react.telemetryoptions.md#telemetryoptions_interface) | Options for initialized the Telemetry service using [getTelemetry()](./telemetry_.md#gettelemetry_448bdc6). | -## function({ firebaseOptions, telemetryOptions }, ...) +## function({ firebaseApp, telemetryOptions }, ...) -### FirebaseTelemetry({ firebaseOptions, telemetryOptions }) {:#firebasetelemetry_f37eb31} +### FirebaseTelemetry({ firebaseApp, telemetryOptions }) {:#firebasetelemetry_10424e8} Registers event listeners for uncaught errors. @@ -35,8 +35,8 @@ This should be installed near the root of your application. Caught errors, inclu Signature: ```typescript -export declare function FirebaseTelemetry({ firebaseOptions, telemetryOptions }: { - firebaseOptions?: FirebaseOptions; +export declare function FirebaseTelemetry({ firebaseApp, telemetryOptions }: { + firebaseApp: FirebaseApp; telemetryOptions?: TelemetryOptions; }): null; ``` @@ -45,7 +45,7 @@ export declare function FirebaseTelemetry({ firebaseOptions, telemetryOptions }: | Parameter | Type | Description | | --- | --- | --- | -| { firebaseOptions, telemetryOptions } | { firebaseOptions?: [FirebaseOptions](./app.firebaseoptions.md#firebaseoptions_interface); telemetryOptions?: [TelemetryOptions](./telemetry_.telemetryoptions.md#telemetryoptions_interface); } | | +| { firebaseApp, telemetryOptions } | { firebaseApp: [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface); telemetryOptions?: [TelemetryOptions](./telemetry_.telemetryoptions.md#telemetryoptions_interface); } | | Returns: @@ -58,7 +58,7 @@ The default [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance ```html - + ... my app ... diff --git a/packages/telemetry/src/react/index.test.tsx b/packages/telemetry/src/react/index.test.tsx index 44ede8922f9..4809c05e090 100644 --- a/packages/telemetry/src/react/index.test.tsx +++ b/packages/telemetry/src/react/index.test.tsx @@ -33,8 +33,6 @@ use(chaiAsPromised); describe('FirebaseTelemetry', () => { let getTelemetryStub: sinon.SinonStub; let captureErrorStub: sinon.SinonStub; - let initializeAppStub: sinon.SinonStub; - let getAppStub: sinon.SinonStub; let fakeApp: FirebaseApp; let fakeTelemetry: Telemetry; @@ -42,36 +40,23 @@ describe('FirebaseTelemetry', () => { fakeApp = { name: 'fakeApp' } as FirebaseApp; fakeTelemetry = {} as Telemetry; - initializeAppStub = stub(app, 'initializeApp').returns(fakeApp); getTelemetryStub = stub(telemetry, 'getTelemetry').returns(fakeTelemetry); captureErrorStub = stub(telemetry, 'captureError'); - getAppStub = stub(app, 'getApp').returns(fakeApp); }); afterEach(() => { restore(); }); - it('gets telemetry with the default app if no firebaseOptions are provided', () => { - render(); - expect(initializeAppStub).not.to.have.been.called; - }); - - it('initializes a new app and gets telemetry if firebaseOptions are provided', () => { - const firebaseOptions = { apiKey: 'test' }; - render(); - expect(initializeAppStub).to.have.been.calledWith(firebaseOptions); - }); - it('captures window errors', done => { - render(); + render(); const error = new Error('test error'); window.onerror = () => { // Prevent error from bubbling up to test suite }; window.addEventListener('error', (event: ErrorEvent) => { // Registers another listener (sequential) to confirm behaviour. - expect(getTelemetryStub).to.have.been.called; + expect(getTelemetryStub).to.have.been.calledWith(fakeApp); expect(captureErrorStub).to.have.been.calledWith(fakeTelemetry, error); done(); }); @@ -79,26 +64,14 @@ describe('FirebaseTelemetry', () => { }); it('captures unhandled promise rejections', () => { - render(); + render(); const reason = new Error('test rejection'); const promise = Promise.reject(reason); promise.catch(() => {}); window.dispatchEvent( new PromiseRejectionEvent('unhandledrejection', { reason, promise }) ); - expect(getTelemetryStub).to.have.been.called; + expect(getTelemetryStub).to.have.been.calledWith(fakeApp); expect(captureErrorStub).to.have.been.calledWith(fakeTelemetry, reason); }); - - it('fails silently when getTelemetry fails', () => { - const error = new Error('getTelemetry failed'); - initializeAppStub.throws(error); - const consoleWarnStub = stub(console, 'warn'); - - expect(() => render()).not.to.throw(); - expect(consoleWarnStub).to.have.been.calledWith( - 'Firebase Telemetry was not initialized:\n', - error - ); - }); }); diff --git a/packages/telemetry/src/react/index.ts b/packages/telemetry/src/react/index.ts index c43d898d41c..3c28327ede4 100644 --- a/packages/telemetry/src/react/index.ts +++ b/packages/telemetry/src/react/index.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { FirebaseOptions, getApp, initializeApp } from '@firebase/app'; +import { FirebaseApp } from '@firebase/app'; import { registerTelemetry } from '../register'; import { captureError, getTelemetry } from '../api'; import { TelemetryOptions } from '../public-types'; @@ -34,22 +34,22 @@ export * from '../public-types'; * @example * ```html * - * + * * ... my app ... * * ``` * - * @param firebaseOptions - Options to run {@link @firebase/app#initializeApp}. If this is not provided, initializeApp needs to be called explicitly elsewhere in your application. + * @param firebaseApp - The {@link @firebase/app#FirebaseApp} instance to use. * @param telemetryOptions - {@link TelemetryOptions} that configure the Telemetry instance. * @returns The default {@link Telemetry} instance for the given {@link @firebase/app#FirebaseApp}. * * @public */ export function FirebaseTelemetry({ - firebaseOptions, + firebaseApp, telemetryOptions }: { - firebaseOptions?: FirebaseOptions; + firebaseApp: FirebaseApp; telemetryOptions?: TelemetryOptions; }): null { useEffect(() => { @@ -58,17 +58,22 @@ export function FirebaseTelemetry({ } const errorListener = (event: ErrorEvent): void => { - captureError(getTelemetry(getApp(), telemetryOptions), event.error, {}); + captureError( + getTelemetry(firebaseApp, telemetryOptions), + event.error, + {} + ); }; const unhandledRejectionListener = (event: PromiseRejectionEvent): void => { - captureError(getTelemetry(getApp(), telemetryOptions), event.reason, {}); + captureError( + getTelemetry(firebaseApp, telemetryOptions), + event.reason, + {} + ); }; try { - if (firebaseOptions) { - initializeApp(firebaseOptions); - } window.addEventListener('error', errorListener); window.addEventListener('unhandledrejection', unhandledRejectionListener); } catch (error) { @@ -82,7 +87,7 @@ export function FirebaseTelemetry({ unhandledRejectionListener ); }; - }, []); + }, [firebaseApp, telemetryOptions]); return null; }