diff --git a/packages/plugins/plugin-firebase/src/FirebasePlugin.tsx b/packages/plugins/plugin-firebase/src/FirebasePlugin.tsx index d26b3eaaf..eab7ff039 100644 --- a/packages/plugins/plugin-firebase/src/FirebasePlugin.tsx +++ b/packages/plugins/plugin-firebase/src/FirebasePlugin.tsx @@ -11,13 +11,14 @@ import screen from './methods/screen'; import track from './methods/track'; import reset from './methods/reset'; import { firebaseAnalytics } from './firebaseAnalytics'; +import { setUserId, setUserProperties } from '@react-native-firebase/analytics'; export class FirebasePlugin extends DestinationPlugin { type = PluginType.destination; key = 'Firebase'; async identify(event: IdentifyEventType) { if (event.userId !== undefined) { - await firebaseAnalytics.setUserId(event.userId); + await setUserId(firebaseAnalytics, event.userId); } if (event.traits) { const eventTraits = event.traits; @@ -45,7 +46,7 @@ export class FirebasePlugin extends DestinationPlugin { {} ); - await firebaseAnalytics.setUserProperties(safeTraits); + await setUserProperties(firebaseAnalytics, safeTraits); } return event; } diff --git a/packages/plugins/plugin-firebase/src/methods/___tests__/identify.test.ts b/packages/plugins/plugin-firebase/src/methods/___tests__/identify.test.ts index 9a957a37f..1151b2884 100644 --- a/packages/plugins/plugin-firebase/src/methods/___tests__/identify.test.ts +++ b/packages/plugins/plugin-firebase/src/methods/___tests__/identify.test.ts @@ -1,11 +1,16 @@ const mockSetUserId = jest.fn(); const mockSetUserProperties = jest.fn(); +const mockDeprecatedSetUserId = jest.fn(); +const mockDeprecatedSetUserProperties = jest.fn(); +const mockAnalytics = { + setUserId: mockDeprecatedSetUserId, + setUserProperties: mockDeprecatedSetUserProperties, +}; jest.mock('@react-native-firebase/analytics', () => ({ - getAnalytics: jest.fn().mockImplementation(() => ({ - setUserId: mockSetUserId, - setUserProperties: mockSetUserProperties, - })), + getAnalytics: jest.fn().mockImplementation(() => mockAnalytics), + setUserId: mockSetUserId, + setUserProperties: mockSetUserProperties, isString: (a: unknown) => typeof a === 'string', })); jest.mock('@react-native-firebase/app', () => ({ @@ -34,7 +39,7 @@ describe('#identify', () => { expect(mockSetUserId).toHaveBeenCalledTimes(1); expect(mockSetUserProperties).not.toHaveBeenCalled(); - expect(mockSetUserId).toHaveBeenCalledWith('123'); + expect(mockSetUserId).toHaveBeenCalledWith(mockAnalytics, '123'); }); it('forwards the identify event with ID and properties', async () => { @@ -54,8 +59,12 @@ describe('#identify', () => { expect(mockSetUserId).toHaveBeenCalledTimes(1); expect(mockSetUserProperties).toHaveBeenCalledTimes(1); - expect(mockSetUserId).toHaveBeenCalledWith('123'); - expect(mockSetUserProperties).toHaveBeenCalledWith({ name: 'Mary' }); + expect(mockSetUserId).toHaveBeenCalledWith(mockAnalytics, '123'); + expect(mockSetUserProperties).toHaveBeenCalledWith(mockAnalytics, { + name: 'Mary', + }); + expect(mockDeprecatedSetUserId).not.toHaveBeenCalled(); + expect(mockDeprecatedSetUserProperties).not.toHaveBeenCalled(); }); it('forwards the identify event without ID', async () => { @@ -74,6 +83,8 @@ describe('#identify', () => { expect(mockSetUserId).not.toHaveBeenCalled(); expect(mockSetUserProperties).toHaveBeenCalledTimes(1); - expect(mockSetUserProperties).toHaveBeenCalledWith({ name: 'Mary' }); + expect(mockSetUserProperties).toHaveBeenCalledWith(mockAnalytics, { + name: 'Mary', + }); }); }); diff --git a/packages/plugins/plugin-firebase/src/methods/___tests__/reset.test.ts b/packages/plugins/plugin-firebase/src/methods/___tests__/reset.test.ts index 3ec925070..f84e52a5e 100644 --- a/packages/plugins/plugin-firebase/src/methods/___tests__/reset.test.ts +++ b/packages/plugins/plugin-firebase/src/methods/___tests__/reset.test.ts @@ -1,9 +1,10 @@ const mockReset = jest.fn(); +const mockDeprecatedReset = jest.fn(); +const mockAnalytics = { resetAnalyticsData: mockDeprecatedReset }; jest.mock('@react-native-firebase/analytics', () => ({ - getAnalytics: jest.fn().mockImplementation(() => ({ - resetAnalyticsData: mockReset, - })), + getAnalytics: jest.fn().mockImplementation(() => mockAnalytics), + resetAnalyticsData: mockReset, })); jest.mock('@react-native-firebase/app', () => ({ @@ -21,6 +22,7 @@ describe('#reset', () => { await reset(); expect(mockReset).toHaveBeenCalledTimes(1); - expect(mockReset).toHaveBeenCalledWith(); + expect(mockReset).toHaveBeenCalledWith(mockAnalytics); + expect(mockDeprecatedReset).not.toHaveBeenCalled(); }); }); diff --git a/packages/plugins/plugin-firebase/src/methods/___tests__/screen.test.ts b/packages/plugins/plugin-firebase/src/methods/___tests__/screen.test.ts index 39c924c27..628253e18 100644 --- a/packages/plugins/plugin-firebase/src/methods/___tests__/screen.test.ts +++ b/packages/plugins/plugin-firebase/src/methods/___tests__/screen.test.ts @@ -1,9 +1,10 @@ -const mockScreen = jest.fn(); +const mockLogEvent = jest.fn(); +const mockDeprecatedLogScreenView = jest.fn(); +const mockAnalytics = { logScreenView: mockDeprecatedLogScreenView }; jest.mock('@react-native-firebase/analytics', () => ({ - getAnalytics: jest.fn().mockImplementation(() => ({ - logScreenView: mockScreen, - })), + getAnalytics: jest.fn().mockImplementation(() => mockAnalytics), + logEvent: mockLogEvent, })); jest.mock('@react-native-firebase/app', () => ({ @@ -30,10 +31,25 @@ describe('#screen', () => { await screen(event); - expect(mockScreen).toHaveBeenCalledTimes(1); - expect(mockScreen).toHaveBeenCalledWith({ + expect(mockLogEvent).toHaveBeenCalledTimes(1); + expect(mockLogEvent).toHaveBeenCalledWith(mockAnalytics, 'screen_view', { screen_name: 'HomeScreen', screen_class: 'HomeScreen', }); }); + + it('does not call the deprecated logScreenView method', async () => { + const event = { + type: 'screen', + name: 'HomeScreen', + anonymousId: 'anon', + messageId: 'message-id', + timestamp: '00000', + properties: {}, + } as ScreenEventType; + + await screen(event); + + expect(mockDeprecatedLogScreenView).not.toHaveBeenCalled(); + }); }); diff --git a/packages/plugins/plugin-firebase/src/methods/___tests__/track.test.ts b/packages/plugins/plugin-firebase/src/methods/___tests__/track.test.ts index 1ae83af93..565d688f2 100644 --- a/packages/plugins/plugin-firebase/src/methods/___tests__/track.test.ts +++ b/packages/plugins/plugin-firebase/src/methods/___tests__/track.test.ts @@ -1,9 +1,10 @@ const mockLogEvent = jest.fn(); +const mockDeprecatedLogEvent = jest.fn(); +const mockAnalytics = { logEvent: mockDeprecatedLogEvent }; jest.mock('@react-native-firebase/analytics', () => ({ - getAnalytics: jest.fn().mockImplementation(() => ({ - logEvent: mockLogEvent, - })), + getAnalytics: jest.fn().mockImplementation(() => mockAnalytics), + logEvent: mockLogEvent, isString: (a: unknown) => typeof a === 'string', })); jest.mock('@react-native-firebase/app', () => ({ @@ -32,7 +33,22 @@ describe('#track', () => { await track(event); expect(mockLogEvent).toHaveBeenCalledTimes(1); - expect(mockLogEvent).toHaveBeenCalledWith('test_event', {}); + expect(mockLogEvent).toHaveBeenCalledWith(mockAnalytics, 'test_event', {}); + }); + + it('uses the modular API instead of the deprecated instance method', async () => { + const event = { + type: EventType.TrackEvent, + event: 'test_event', + anonymousId: 'anon', + messageId: 'message-id', + timestamp: '00000', + properties: {}, + } as TrackEventType; + + await track(event); + + expect(mockDeprecatedLogEvent).not.toHaveBeenCalled(); }); it('forwards a track event with name and properties', async () => { @@ -48,9 +64,13 @@ describe('#track', () => { await track(event); expect(mockLogEvent).toHaveBeenCalledTimes(1); - expect(mockLogEvent).toHaveBeenCalledWith('another_test_event', { - foo: 'bar', - }); + expect(mockLogEvent).toHaveBeenCalledWith( + mockAnalytics, + 'another_test_event', + { + foo: 'bar', + } + ); }); it('removes non-alphanumeric characters from', async () => { @@ -67,6 +87,7 @@ describe('#track', () => { expect(mockLogEvent).toHaveBeenCalledTimes(1); expect(mockLogEvent).toHaveBeenCalledWith( + mockAnalytics, 'yet_another__test____event_CAPS', {} ); @@ -85,6 +106,6 @@ describe('#track', () => { await track(event); expect(mockLogEvent).toHaveBeenCalledTimes(1); - expect(mockLogEvent).toHaveBeenCalledWith('refund', {}); + expect(mockLogEvent).toHaveBeenCalledWith(mockAnalytics, 'refund', {}); }); }); diff --git a/packages/plugins/plugin-firebase/src/methods/reset.ts b/packages/plugins/plugin-firebase/src/methods/reset.ts index ae8937b17..99fe5b1a0 100644 --- a/packages/plugins/plugin-firebase/src/methods/reset.ts +++ b/packages/plugins/plugin-firebase/src/methods/reset.ts @@ -1,5 +1,6 @@ +import { resetAnalyticsData } from '@react-native-firebase/analytics'; import { firebaseAnalytics } from '../firebaseAnalytics'; export default async () => { - await firebaseAnalytics.resetAnalyticsData(); + await resetAnalyticsData(firebaseAnalytics); }; diff --git a/packages/plugins/plugin-firebase/src/methods/screen.ts b/packages/plugins/plugin-firebase/src/methods/screen.ts index 538886343..e15a9b376 100644 --- a/packages/plugins/plugin-firebase/src/methods/screen.ts +++ b/packages/plugins/plugin-firebase/src/methods/screen.ts @@ -1,4 +1,5 @@ import type { ScreenEventType } from '@segment/analytics-react-native'; +import { logEvent } from '@react-native-firebase/analytics'; import { firebaseAnalytics } from '../firebaseAnalytics'; export default async (event: ScreenEventType) => { @@ -8,5 +9,9 @@ export default async (event: ScreenEventType) => { ...event.properties, }; - await firebaseAnalytics.logScreenView(screenProps); + // logScreenView is deprecated in both the namespaced and modular APIs. + // The typings of the 'screen_view' overload use the web parameter names + // (firebase_screen), but the native SDKs read screen_name and screen_class, + // which is what logScreenView forwarded. Keep the payload and cast the type. + await logEvent(firebaseAnalytics, 'screen_view', screenProps as never); }; diff --git a/packages/plugins/plugin-firebase/src/methods/track.ts b/packages/plugins/plugin-firebase/src/methods/track.ts index 330fd4e34..01638242b 100644 --- a/packages/plugins/plugin-firebase/src/methods/track.ts +++ b/packages/plugins/plugin-firebase/src/methods/track.ts @@ -2,6 +2,7 @@ import { type TrackEventType, generateMapTransform, } from '@segment/analytics-react-native'; +import { logEvent } from '@react-native-firebase/analytics'; import { firebaseAnalytics } from '../firebaseAnalytics'; import { mapEventProps, transformMap } from './parameterMapping'; @@ -22,5 +23,5 @@ export default async (event: TrackEventType) => { if (safeEventName.length > 40) { safeEventName = safeEventName.substring(0, 40); } - await firebaseAnalytics.logEvent(safeEventName, safeProps); + await logEvent(firebaseAnalytics, safeEventName, safeProps); };