diff --git a/jest.setup.ts b/jest.setup.ts index 8257b2ba28..cc15b33e9b 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -32,6 +32,9 @@ jest.doMock('react-native', () => { OS: 'android', select: () => {}, }, + AppRegistry: { + registerHeadlessTask: jest.fn(), + }, NativeModules: { ...ReactNative.NativeModules, RNFBAnalyticsModule: { diff --git a/packages/app/lib/common/index.js b/packages/app/lib/common/index.js index e636c5c46c..692bcf33bd 100644 --- a/packages/app/lib/common/index.js +++ b/packages/app/lib/common/index.js @@ -337,6 +337,47 @@ const mapOfDeprecationReplacements = { nanoseconds: NO_REPLACEMENT, }, }, + messaging: { + default: { + isAutoInitEnabled: 'isAutoInitEnabled()', + isDeviceRegisteredForRemoteMessages: 'isDeviceRegisteredForRemoteMessages()', + isNotificationDelegationEnabled: 'isNotificationDelegationEnabled()', + isDeliveryMetricsExportToBigQueryEnabled: 'isDeliveryMetricsExportToBigQueryEnabled()', + setAutoInitEnabled: 'setAutoInitEnabled()', + getInitialNotification: 'getInitialNotification()', + getDidOpenSettingsForNotification: 'getDidOpenSettingsForNotification()', + getIsHeadless: 'getIsHeadless()', + onNotificationOpenedApp: 'onNotificationOpenedApp()', + onTokenRefresh: 'onTokenRefresh()', + requestPermission: 'requestPermission()', + registerDeviceForRemoteMessages: 'registerDeviceForRemoteMessages()', + unregisterDeviceForRemoteMessages: 'unregisterDeviceForRemoteMessages()', + getAPNSToken: 'getAPNSToken()', + setAPNSToken: 'setAPNSToken()', + hasPermission: 'hasPermission()', + onDeletedMessages: 'onDeletedMessages()', + onMessageSent: 'onMessageSent()', + onSendError: 'onSendError()', + setBackgroundMessageHandler: 'setBackgroundMessageHandler()', + setOpenSettingsForNotificationsHandler: 'setOpenSettingsForNotificationsHandler()', + sendMessage: 'sendMessage()', + subscribeToTopic: 'subscribeToTopic()', + unsubscribeFromTopic: 'unsubscribeFromTopic()', + setNotificationDelegationEnabled: 'setNotificationDelegationEnabled()', + // Actual firebase-js-sdk methods + getToken: 'getToken()', + deleteToken: 'deleteToken()', + onMessage: 'onMessage()', + isSupported: 'isSupported()', + setDeliveryMetricsExportToBigQuery: + 'experimentalSetDeliveryMetricsExportedToBigQueryEnabled()', + }, + statics: { + AuthorizationStatus: 'AuthorizationStatus', + NotificationAndroidPriority: 'NotificationAndroidPriority', + NotificationAndroidVisibility: 'NotificationAndroidVisibility', + }, + }, remoteConfig: { default: { activate: 'activate()', @@ -553,12 +594,44 @@ export function createDeprecationProxy(instance) { deprecationConsoleWarning('auth', prop, 'statics', false); } + if ( + prop === 'AuthorizationStatus' || + prop === 'NotificationAndroidPriority' || + prop === 'NotificationAndroidVisibility' + ) { + deprecationConsoleWarning('messaging', prop, 'statics', false); + } + if (prop !== 'setLogLevel') { // we want to capture setLogLevel function call which we do below return Reflect.get(target, prop, receiver); } } + // Check if it's a getter/setter first + const descriptor = + Object.getOwnPropertyDescriptor(target, prop) || + Object.getOwnPropertyDescriptor(Object.getPrototypeOf(target), prop); + + if (descriptor && (descriptor.get || descriptor.set)) { + const instanceName = getInstanceName(target); + const nameSpace = getNamespace(target); + + if (descriptor.get) { + // Handle getter - call it and show deprecation warning + deprecationConsoleWarning(nameSpace, prop, instanceName, _isModularCall); + return descriptor.get.call(target); + } + + if (descriptor.set) { + // Handle setter - return a function that calls the setter with deprecation warning + return function (value) { + deprecationConsoleWarning(nameSpace, prop, instanceName, _isModularCall); + descriptor.set.call(target, value); + }; + } + } + if (typeof originalMethod === 'function') { return function (...args) { const isModularMethod = args.includes(MODULAR_DEPRECATION_ARG); @@ -577,6 +650,19 @@ export function createDeprecationProxy(instance) { export const MODULAR_DEPRECATION_ARG = 'react-native-firebase-modular-method-call'; +// Flag to track if we're currently in a modular call +let _isModularCall = false; + +export function withModularFlag(fn) { + const previousFlag = _isModularCall; + _isModularCall = true; + try { + return fn(); + } finally { + _isModularCall = previousFlag; + } +} + export function filterModularArgument(list) { return list.filter(arg => arg !== MODULAR_DEPRECATION_ARG); } diff --git a/packages/messaging/__tests__/messaging.test.ts b/packages/messaging/__tests__/messaging.test.ts index c5f06b8412..9accfaee3b 100644 --- a/packages/messaging/__tests__/messaging.test.ts +++ b/packages/messaging/__tests__/messaging.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, it } from '@jest/globals'; +import { beforeEach, describe, expect, it, jest } from '@jest/globals'; -import { +import messaging, { getMessaging, deleteToken, getToken, @@ -35,7 +35,15 @@ import { NotificationAndroidVisibility, } from '../lib'; -describe('Firestore', function () { +import { + createCheckV9Deprecation, + CheckV9DeprecationFunction, +} from '../../app/lib/common/unitTestUtils'; + +// @ts-ignore test +import FirebaseModule from '../../app/lib/internal/FirebaseModule'; + +describe('Messaging', function () { describe('modular', function () { it('`getMessaging` function is properly exposed to end user', function () { expect(getMessaging).toBeDefined(); @@ -175,4 +183,217 @@ describe('Firestore', function () { expect(NotificationAndroidVisibility.VISIBILITY_SECRET).toBeDefined(); }); }); + + describe('test `console.warn` is called for RNFB v8 API & not called for v9 API', function () { + let messagingV9Deprecation: CheckV9DeprecationFunction; + let staticsV9Deprecation: CheckV9DeprecationFunction; + + beforeEach(function () { + messagingV9Deprecation = createCheckV9Deprecation(['messaging']); + staticsV9Deprecation = createCheckV9Deprecation(['messaging', 'statics']); + + // @ts-ignore test + jest.spyOn(FirebaseModule.prototype, 'native', 'get').mockImplementation(() => { + return new Proxy( + {}, + { + get: () => + jest.fn().mockResolvedValue({ + result: true, + } as never), + }, + ); + }); + }); + + describe('Messaging', function () { + it('isAutoInitEnabled', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => isAutoInitEnabled(messaging), + () => messaging.isAutoInitEnabled, + 'isAutoInitEnabled', + ); + }); + + it('isDeviceRegisteredForRemoteMessages', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => isDeviceRegisteredForRemoteMessages(messaging), + () => messaging.isDeviceRegisteredForRemoteMessages, + 'isDeviceRegisteredForRemoteMessages', + ); + }); + + it('setAutoInitEnabled', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => setAutoInitEnabled(messaging, true), + () => messaging.setAutoInitEnabled(true), + 'setAutoInitEnabled', + ); + }); + + it('getInitialNotification', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => getInitialNotification(messaging), + () => messaging.getInitialNotification(), + 'getInitialNotification', + ); + }); + + it('getDidOpenSettingsForNotification', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => getDidOpenSettingsForNotification(messaging), + () => messaging.getDidOpenSettingsForNotification(), + 'getDidOpenSettingsForNotification', + ); + }); + + it('getIsHeadless', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => getIsHeadless(messaging), + () => messaging.getIsHeadless(), + 'getIsHeadless', + ); + }); + + it('requestPermission', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => requestPermission(messaging), + () => messaging.requestPermission(), + 'requestPermission', + ); + }); + + it('registerDeviceForRemoteMessages', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => registerDeviceForRemoteMessages(messaging), + () => messaging.registerDeviceForRemoteMessages(), + 'registerDeviceForRemoteMessages', + ); + }); + + it('unregisterDeviceForRemoteMessages', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => unregisterDeviceForRemoteMessages(messaging), + () => messaging.unregisterDeviceForRemoteMessages(), + 'unregisterDeviceForRemoteMessages', + ); + }); + + it('getAPNSToken', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => getAPNSToken(messaging), + () => messaging.getAPNSToken(), + 'getAPNSToken', + ); + }); + + it('setAPNSToken', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => setAPNSToken(messaging, 'token'), + () => messaging.setAPNSToken('token'), + 'setAPNSToken', + ); + }); + + it('hasPermission', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => hasPermission(messaging), + () => messaging.hasPermission(), + 'hasPermission', + ); + }); + + it('subscribeToTopic', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => subscribeToTopic(messaging, 'topic'), + () => messaging.subscribeToTopic('topic'), + 'subscribeToTopic', + ); + }); + + it('unsubscribeFromTopic', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => unsubscribeFromTopic(messaging, 'topic'), + () => messaging.unsubscribeFromTopic('topic'), + 'unsubscribeFromTopic', + ); + }); + + it('getToken', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => getToken(messaging), + () => messaging.getToken(), + 'getToken', + ); + }); + + it('deleteToken', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => deleteToken(messaging), + () => messaging.deleteToken(), + 'deleteToken', + ); + }); + + it('isSupported', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => isSupported(messaging), + () => messaging.isSupported(), + 'isSupported', + ); + }); + + it('experimentalSetDeliveryMetricsExportedToBigQueryEnabled', function () { + const messaging = getMessaging(); + messagingV9Deprecation( + () => experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true), + () => messaging.setDeliveryMetricsExportToBigQuery(true), + 'setDeliveryMetricsExportToBigQuery', + ); + }); + + describe('statics', function () { + it('AuthorizationStatus', function () { + staticsV9Deprecation( + () => AuthorizationStatus, + () => messaging.AuthorizationStatus, + 'AuthorizationStatus', + ); + }); + + it('NotificationAndroidPriority', function () { + staticsV9Deprecation( + () => NotificationAndroidPriority, + () => messaging.NotificationAndroidPriority, + 'NotificationAndroidPriority', + ); + }); + + it('NotificationAndroidVisibility', function () { + staticsV9Deprecation( + () => NotificationAndroidVisibility, + () => messaging.NotificationAndroidVisibility, + 'NotificationAndroidVisibility', + ); + }); + }); + }); + }); }); diff --git a/packages/messaging/lib/modular/index.js b/packages/messaging/lib/modular/index.js index 0182990fb2..0a4adb6781 100644 --- a/packages/messaging/lib/modular/index.js +++ b/packages/messaging/lib/modular/index.js @@ -1,4 +1,6 @@ import { getApp } from '@react-native-firebase/app'; +import { withModularFlag } from '@react-native-firebase/app/lib/common'; +import { MODULAR_DEPRECATION_ARG } from '@react-native-firebase/app/lib/common'; /** * @typedef {import('..').FirebaseMessagingTypes} FirebaseMessagingTypes @@ -33,7 +35,7 @@ export function getMessaging(app) { * @returns {Promise} */ export function deleteToken(messaging, tokenOptions) { - return messaging.deleteToken(tokenOptions); + return messaging.deleteToken.call(messaging, tokenOptions, MODULAR_DEPRECATION_ARG); } /** @@ -43,7 +45,7 @@ export function deleteToken(messaging, tokenOptions) { * @returns {Promise} */ export function getToken(messaging, options) { - return messaging.getToken(options); + return messaging.getToken.call(messaging, options, MODULAR_DEPRECATION_ARG); } /** @@ -54,7 +56,7 @@ export function getToken(messaging, options) { * @returns {() => void} */ export function onMessage(messaging, listener) { - return messaging.onMessage(listener); + return messaging.onMessage.call(messaging, listener, MODULAR_DEPRECATION_ARG); } /** @@ -65,7 +67,7 @@ export function onMessage(messaging, listener) { * @returns {() => void} */ export function onNotificationOpenedApp(messaging, listener) { - return messaging.onNotificationOpenedApp(listener); + return messaging.onNotificationOpenedApp.call(messaging, listener, MODULAR_DEPRECATION_ARG); } /** @@ -77,7 +79,7 @@ export function onNotificationOpenedApp(messaging, listener) { * @returns {() => void} */ export function onTokenRefresh(messaging, listener) { - return messaging.onTokenRefresh(listener); + return messaging.onTokenRefresh.call(messaging, listener, MODULAR_DEPRECATION_ARG); } /** @@ -88,7 +90,7 @@ export function onTokenRefresh(messaging, listener) { * @returns {Promise} */ export function requestPermission(messaging, iosPermissions) { - return messaging.requestPermission(iosPermissions); + return messaging.requestPermission.call(messaging, iosPermissions, MODULAR_DEPRECATION_ARG); } /** @@ -97,7 +99,7 @@ export function requestPermission(messaging, iosPermissions) { * @returns {boolean} */ export function isAutoInitEnabled(messaging) { - return messaging.isAutoInitEnabled; + return withModularFlag(() => messaging.isAutoInitEnabled); } /** @@ -107,7 +109,7 @@ export function isAutoInitEnabled(messaging) { * @returns {Promise} */ export function setAutoInitEnabled(messaging, enabled) { - return messaging.setAutoInitEnabled(enabled); + return messaging.setAutoInitEnabled.call(messaging, enabled, MODULAR_DEPRECATION_ARG); } /** @@ -118,7 +120,7 @@ export function setAutoInitEnabled(messaging, enabled) { * @returns {Promise} */ export function getInitialNotification(messaging) { - return messaging.getInitialNotification(); + return messaging.getInitialNotification.call(messaging, MODULAR_DEPRECATION_ARG); } /** @@ -128,7 +130,7 @@ export function getInitialNotification(messaging) { * @returns {Promise} */ export function getDidOpenSettingsForNotification(messaging) { - return messaging.getDidOpenSettingsForNotification(); + return messaging.getDidOpenSettingsForNotification.call(messaging, MODULAR_DEPRECATION_ARG); } /** @@ -138,7 +140,7 @@ export function getDidOpenSettingsForNotification(messaging) { * @returns {Promise} */ export function getIsHeadless(messaging) { - return messaging.getIsHeadless(); + return messaging.getIsHeadless.call(messaging, MODULAR_DEPRECATION_ARG); } /** @@ -148,7 +150,7 @@ export function getIsHeadless(messaging) { * @returns {Promise} */ export function registerDeviceForRemoteMessages(messaging) { - return messaging.registerDeviceForRemoteMessages(); + return messaging.registerDeviceForRemoteMessages.call(messaging, MODULAR_DEPRECATION_ARG); } /** @@ -158,7 +160,7 @@ export function registerDeviceForRemoteMessages(messaging) { * @returns {boolean} */ export function isDeviceRegisteredForRemoteMessages(messaging) { - return messaging.isDeviceRegisteredForRemoteMessages; + return withModularFlag(() => messaging.isDeviceRegisteredForRemoteMessages); } /** @@ -167,7 +169,7 @@ export function isDeviceRegisteredForRemoteMessages(messaging) { * @returns {Promise} */ export function unregisterDeviceForRemoteMessages(messaging) { - return messaging.unregisterDeviceForRemoteMessages(); + return messaging.unregisterDeviceForRemoteMessages.call(messaging, MODULAR_DEPRECATION_ARG); } /** @@ -177,7 +179,7 @@ export function unregisterDeviceForRemoteMessages(messaging) { * @returns {Promise} */ export function getAPNSToken(messaging) { - return messaging.getAPNSToken(); + return messaging.getAPNSToken.call(messaging, MODULAR_DEPRECATION_ARG); } /** @@ -204,7 +206,7 @@ export function getAPNSToken(messaging) { * @returns {Promise} */ export function setAPNSToken(messaging, token, type) { - return messaging.setAPNSToken(token, type); + return messaging.setAPNSToken.call(messaging, token, type, MODULAR_DEPRECATION_ARG); } /** @@ -213,7 +215,7 @@ export function setAPNSToken(messaging, token, type) { * @returns {Promise} */ export function hasPermission(messaging) { - return messaging.hasPermission(); + return messaging.hasPermission.call(messaging, MODULAR_DEPRECATION_ARG); } /** @@ -223,7 +225,7 @@ export function hasPermission(messaging) { * @returns {() => void} */ export function onDeletedMessages(messaging, listener) { - return messaging.onDeletedMessages(listener); + return messaging.onDeletedMessages.call(messaging, listener, MODULAR_DEPRECATION_ARG); } /** @@ -233,7 +235,7 @@ export function onDeletedMessages(messaging, listener) { * @returns {() => void} */ export function onMessageSent(messaging, listener) { - return messaging.onMessageSent(listener); + return messaging.onMessageSent.call(messaging, listener, MODULAR_DEPRECATION_ARG); } /** @@ -243,7 +245,7 @@ export function onMessageSent(messaging, listener) { * @returns {() => void} */ export function onSendError(messaging, listener) { - return messaging.onSendError(listener); + return messaging.onSendError.call(messaging, listener, MODULAR_DEPRECATION_ARG); } /** @@ -255,7 +257,7 @@ export function onSendError(messaging, listener) { * @returns {void} */ export function setBackgroundMessageHandler(messaging, handler) { - return messaging.setBackgroundMessageHandler(handler); + return messaging.setBackgroundMessageHandler.call(messaging, handler, MODULAR_DEPRECATION_ARG); } /** @@ -266,7 +268,11 @@ export function setBackgroundMessageHandler(messaging, handler) { * @returns {void} */ export function setOpenSettingsForNotificationsHandler(messaging, handler) { - return messaging.setOpenSettingsForNotificationsHandler(handler); + return messaging.setOpenSettingsForNotificationsHandler.call( + messaging, + handler, + MODULAR_DEPRECATION_ARG, + ); } /** @@ -276,7 +282,7 @@ export function setOpenSettingsForNotificationsHandler(messaging, handler) { * @returns {Promise} */ export function sendMessage(messaging, message) { - return messaging.sendMessage(message); + return messaging.sendMessage.call(messaging, message, MODULAR_DEPRECATION_ARG); } /** @@ -287,7 +293,7 @@ export function sendMessage(messaging, message) { * @returns {Promise} */ export function subscribeToTopic(messaging, topic) { - return messaging.subscribeToTopic(topic); + return messaging.subscribeToTopic.call(messaging, topic, MODULAR_DEPRECATION_ARG); } /** @@ -297,7 +303,7 @@ export function subscribeToTopic(messaging, topic) { * @returns {Promise} */ export function unsubscribeFromTopic(messaging, topic) { - return messaging.unsubscribeFromTopic(topic); + return messaging.unsubscribeFromTopic.call(messaging, topic, MODULAR_DEPRECATION_ARG); } /** @@ -306,7 +312,7 @@ export function unsubscribeFromTopic(messaging, topic) { * @returns {boolean} */ export function isDeliveryMetricsExportToBigQueryEnabled(messaging) { - return messaging.isDeliveryMetricsExportToBigQueryEnabled; + return withModularFlag(() => messaging.isDeliveryMetricsExportToBigQueryEnabled); } /** @@ -316,7 +322,7 @@ export function isDeliveryMetricsExportToBigQueryEnabled(messaging) { * @returns {boolean} */ export function isNotificationDelegationEnabled(messaging) { - return messaging.isNotificationDelegationEnabled; + return withModularFlag(() => messaging.isNotificationDelegationEnabled); } /** @@ -328,7 +334,11 @@ export function isNotificationDelegationEnabled(messaging) { * @returns {Promise} */ export function setNotificationDelegationEnabled(messaging, enabled) { - return messaging.setNotificationDelegationEnabled(enabled); + return messaging.setNotificationDelegationEnabled.call( + messaging, + enabled, + MODULAR_DEPRECATION_ARG, + ); } /** @@ -337,7 +347,7 @@ export function setNotificationDelegationEnabled(messaging, enabled) { * @returns {boolean} */ export function isSupported(messaging) { - return messaging.isSupported(); + return messaging.isSupported.call(messaging, MODULAR_DEPRECATION_ARG); } /** @@ -348,7 +358,11 @@ export function isSupported(messaging) { * @returns {Promise} */ export function experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, enabled) { - return messaging.setDeliveryMetricsExportToBigQuery(enabled); + return messaging.setDeliveryMetricsExportToBigQuery.call( + messaging, + enabled, + MODULAR_DEPRECATION_ARG, + ); } export {