@react-native-firebase/messaging 25.1.0 → 26.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/RNFBMessaging.podspec +27 -8
  3. package/android/build.gradle +24 -0
  4. package/android/src/main/java/io/invertase/firebase/messaging/{ReactNativeFirebaseMessagingModule.java → NativeRNFBTurboMessaging.java} +143 -81
  5. package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingPackage.java +1 -1
  6. package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingReceiver.java +16 -0
  7. package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingStoreImpl.java +50 -11
  8. package/android/src/main/java/io/invertase/firebase/messaging/generated/java/com/facebook/fbreact/specs/NativeRNFBTurboMessagingSpec.java +151 -0
  9. package/android/src/main/java/io/invertase/firebase/messaging/generated/jni/CMakeLists.txt +36 -0
  10. package/android/src/main/java/io/invertase/firebase/messaging/generated/jni/RNFBMessagingTurboModules-generated.cpp +152 -0
  11. package/android/src/main/java/io/invertase/firebase/messaging/generated/jni/RNFBMessagingTurboModules.h +31 -0
  12. package/android/src/main/java/io/invertase/firebase/messaging/generated/jni/react/renderer/components/RNFBMessagingTurboModules/RNFBMessagingTurboModulesJSI-generated.cpp +161 -0
  13. package/android/src/main/java/io/invertase/firebase/messaging/generated/jni/react/renderer/components/RNFBMessagingTurboModules/RNFBMessagingTurboModulesJSI.h +356 -0
  14. package/app.plugin.js +1 -1
  15. package/dist/module/index.js +622 -7
  16. package/dist/module/index.js.map +1 -1
  17. package/dist/module/statics.js +1 -1
  18. package/dist/module/types/internal.js +4 -0
  19. package/dist/module/types/internal.js.map +1 -0
  20. package/dist/module/types/messaging.js +0 -15
  21. package/dist/module/types/messaging.js.map +1 -1
  22. package/dist/module/version.js +1 -1
  23. package/dist/typescript/lib/index.d.ts +182 -5
  24. package/dist/typescript/lib/index.d.ts.map +1 -1
  25. package/dist/typescript/lib/types/internal.d.ts +41 -0
  26. package/dist/typescript/lib/types/internal.d.ts.map +1 -0
  27. package/dist/typescript/lib/types/messaging.d.ts +7 -55
  28. package/dist/typescript/lib/types/messaging.d.ts.map +1 -1
  29. package/dist/typescript/lib/version.d.ts +1 -1
  30. package/ios/RNFBMessaging/RNFBMessaging+AppDelegate.h +24 -2
  31. package/ios/RNFBMessaging/RNFBMessaging+AppDelegate.m +90 -12
  32. package/ios/RNFBMessaging/RNFBMessaging+FIRMessagingDelegate.h +8 -0
  33. package/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m +22 -4
  34. package/ios/RNFBMessaging/RNFBMessaging+UNUserNotificationCenter.m +31 -28
  35. package/ios/RNFBMessaging/RNFBMessagingModule.h +3 -2
  36. package/ios/RNFBMessaging/RNFBMessagingModule.mm +508 -0
  37. package/ios/RNFBMessaging/RNFBMessagingSerializer.h +8 -0
  38. package/ios/RNFBMessaging.xcodeproj/project.pbxproj +8 -8
  39. package/ios/generated/RCTAppDependencyProvider.h +25 -0
  40. package/ios/generated/RCTAppDependencyProvider.mm +55 -0
  41. package/ios/generated/RCTModulesConformingToProtocolsProvider.h +18 -0
  42. package/ios/generated/RCTModulesConformingToProtocolsProvider.mm +33 -0
  43. package/ios/generated/RCTThirdPartyComponentsProvider.h +16 -0
  44. package/ios/generated/RCTThirdPartyComponentsProvider.mm +23 -0
  45. package/ios/generated/RNFBMessagingTurboModules/RNFBMessagingTurboModules-generated.mm +184 -0
  46. package/ios/generated/RNFBMessagingTurboModules/RNFBMessagingTurboModules.h +222 -0
  47. package/ios/generated/RNFBMessagingTurboModulesJSI-generated.cpp +161 -0
  48. package/ios/generated/RNFBMessagingTurboModulesJSI.h +356 -0
  49. package/ios/generated/ReactAppDependencyProvider.podspec +34 -0
  50. package/lib/index.ts +821 -15
  51. package/lib/statics.ts +1 -1
  52. package/lib/types/internal.ts +59 -0
  53. package/lib/types/messaging.ts +7 -72
  54. package/lib/version.ts +1 -1
  55. package/package.json +30 -5
  56. package/plugin/build/android/setupFirebaseNotifationIcon.d.ts +3 -2
  57. package/plugin/build/android/setupFirebaseNotifationIcon.js +14 -7
  58. package/plugin/build/app.plugin.d.ts +2 -0
  59. package/plugin/build/app.plugin.js +6 -0
  60. package/plugin/build/index.d.ts +2 -1
  61. package/plugin/build/index.js +4 -4
  62. package/plugin/build/pluginConfig.d.ts +7 -0
  63. package/plugin/build/pluginConfig.js +2 -0
  64. package/plugin/src/android/setupFirebaseNotifationIcon.ts +19 -6
  65. package/plugin/src/app.plugin.ts +3 -0
  66. package/plugin/src/index.ts +5 -4
  67. package/plugin/src/pluginConfig.ts +8 -0
  68. package/plugin/tsconfig.tsbuildinfo +1 -1
  69. package/react-native.config.js +10 -0
  70. package/specs/NativeRNFBTurboMessaging.ts +46 -0
  71. package/typedoc.json +2 -19
  72. package/dist/module/modular.js +0 -396
  73. package/dist/module/modular.js.map +0 -1
  74. package/dist/module/namespaced.js +0 -415
  75. package/dist/module/namespaced.js.map +0 -1
  76. package/dist/typescript/lib/modular.d.ts +0 -255
  77. package/dist/typescript/lib/modular.d.ts.map +0 -1
  78. package/dist/typescript/lib/namespaced.d.ts +0 -12
  79. package/dist/typescript/lib/namespaced.d.ts.map +0 -1
  80. package/ios/RNFBMessaging/RNFBMessagingModule.m +0 -439
  81. package/lib/modular.ts +0 -455
  82. package/lib/namespaced.ts +0 -593
package/lib/index.ts CHANGED
@@ -15,7 +15,827 @@
15
15
  *
16
16
  */
17
17
 
18
- // Export types from types/messaging
18
+ import {
19
+ hasOwnProperty,
20
+ isAndroid,
21
+ isBoolean,
22
+ isFunction,
23
+ isIOS,
24
+ isObject,
25
+ isString,
26
+ isUndefined,
27
+ } from '@react-native-firebase/app/dist/module/common';
28
+ import {
29
+ FirebaseModule,
30
+ getOrCreateModularInstance,
31
+ } from '@react-native-firebase/app/dist/module/internal';
32
+ import type { ModuleConfig } from '@react-native-firebase/app/dist/module/internal';
33
+ import { getReactNativeModule } from '@react-native-firebase/app/dist/module/internal/nativeModule';
34
+ import { UTILS_NATIVE_MODULE } from '@react-native-firebase/app/dist/module/internal/constants';
35
+ import './types/internal';
36
+ import type { FirebaseApp } from '@react-native-firebase/app';
37
+ import type { ReactNativeFirebase } from '@react-native-firebase/app';
38
+ import { AppRegistry } from 'react-native';
39
+ import remoteMessageOptions from './remoteMessageOptions';
40
+ import {
41
+ AuthorizationStatus,
42
+ NotificationAndroidPriority,
43
+ NotificationAndroidVisibility,
44
+ } from './statics';
45
+ import type {
46
+ Messaging,
47
+ RemoteMessage,
48
+ IOSPermissions,
49
+ AuthorizationStatus as AuthorizationStatusType,
50
+ NativeTokenOptions,
51
+ GetTokenOptions,
52
+ SendErrorEvent,
53
+ } from './types/messaging';
54
+ import { version } from './version';
55
+
56
+ const nativeModuleName = 'NativeRNFBTurboMessaging';
57
+
58
+ let backgroundMessageHandler: ((remoteMessage: RemoteMessage) => Promise<any>) | undefined;
59
+ let openSettingsForNotificationHandler: ((remoteMessage: RemoteMessage) => any) | undefined;
60
+
61
+ class FirebaseMessagingModule extends FirebaseModule<typeof nativeModuleName> implements Messaging {
62
+ _isAutoInitEnabled: boolean;
63
+ _isDeliveryMetricsExportToBigQueryEnabled: boolean;
64
+ _isRegisteredForRemoteNotifications: boolean;
65
+ _isNotificationDelegationEnabled: boolean;
66
+
67
+ constructor(
68
+ app: ReactNativeFirebase.FirebaseAppBase,
69
+ config: ModuleConfig,
70
+ customUrlOrRegion?: string | null,
71
+ ) {
72
+ super(app, config, customUrlOrRegion);
73
+ this._isAutoInitEnabled =
74
+ this.native.isAutoInitEnabled != null ? this.native.isAutoInitEnabled : true;
75
+ this._isDeliveryMetricsExportToBigQueryEnabled =
76
+ this.native.isDeliveryMetricsExportToBigQueryEnabled != null
77
+ ? this.native.isDeliveryMetricsExportToBigQueryEnabled
78
+ : false;
79
+ this._isRegisteredForRemoteNotifications =
80
+ this.native.isRegisteredForRemoteNotifications != null
81
+ ? this.native.isRegisteredForRemoteNotifications
82
+ : true;
83
+ this._isNotificationDelegationEnabled =
84
+ this.native.getConstants?.()?.isNotificationDelegationEnabled ?? false;
85
+
86
+ AppRegistry.registerHeadlessTask('ReactNativeFirebaseMessagingHeadlessTask', () => {
87
+ if (!backgroundMessageHandler) {
88
+ // eslint-disable-next-line no-console
89
+ console.warn(
90
+ 'No background message handler has been set. Set a handler via the "setBackgroundMessageHandler" method.',
91
+ );
92
+ return () => Promise.resolve();
93
+ }
94
+ return (remoteMessage: RemoteMessage) => backgroundMessageHandler!(remoteMessage);
95
+ });
96
+
97
+ if (isIOS) {
98
+ this.emitter.addListener(
99
+ 'messaging_message_received_background',
100
+ (remoteMessage: RemoteMessage) => {
101
+ if (!backgroundMessageHandler) {
102
+ // eslint-disable-next-line no-console
103
+ console.warn(
104
+ 'No background message handler has been set. Set a handler via the "setBackgroundMessageHandler" method.',
105
+ );
106
+ return Promise.resolve();
107
+ }
108
+
109
+ const handlerPromise = Promise.resolve(backgroundMessageHandler(remoteMessage));
110
+ handlerPromise.finally(() => {
111
+ this.native.completeNotificationProcessing();
112
+ });
113
+
114
+ return handlerPromise;
115
+ },
116
+ );
117
+
118
+ this.emitter.addListener(
119
+ 'messaging_settings_for_notification_opened',
120
+ (remoteMessage: RemoteMessage) => {
121
+ if (!openSettingsForNotificationHandler) {
122
+ // eslint-disable-next-line no-console
123
+ console.warn(
124
+ 'No handler for notification settings link has been set. Set a handler via the "setOpenSettingsForNotificationsHandler" method',
125
+ );
126
+
127
+ return Promise.resolve();
128
+ }
129
+
130
+ return openSettingsForNotificationHandler(remoteMessage);
131
+ },
132
+ );
133
+ }
134
+ }
135
+
136
+ get isAutoInitEnabled(): boolean {
137
+ return this._isAutoInitEnabled;
138
+ }
139
+
140
+ /**
141
+ * @ios
142
+ */
143
+ get isDeviceRegisteredForRemoteMessages(): boolean {
144
+ if (isAndroid) {
145
+ return true;
146
+ }
147
+
148
+ return this._isRegisteredForRemoteNotifications;
149
+ }
150
+
151
+ get isNotificationDelegationEnabled(): boolean {
152
+ return this._isNotificationDelegationEnabled;
153
+ }
154
+
155
+ get isDeliveryMetricsExportToBigQueryEnabled(): boolean {
156
+ return this._isDeliveryMetricsExportToBigQueryEnabled;
157
+ }
158
+
159
+ setAutoInitEnabled(enabled: boolean): Promise<void> {
160
+ if (!isBoolean(enabled)) {
161
+ throw new Error("getMessaging().setAutoInitEnabled(*) 'enabled' expected a boolean value.");
162
+ }
163
+
164
+ this._isAutoInitEnabled = enabled;
165
+ return this.native.setAutoInitEnabled(enabled);
166
+ }
167
+
168
+ getInitialNotification(): Promise<RemoteMessage | null> {
169
+ return this.native.getInitialNotification().then((value: RemoteMessage | null) => {
170
+ if (value) {
171
+ return value;
172
+ }
173
+ return null;
174
+ });
175
+ }
176
+
177
+ getDidOpenSettingsForNotification(): Promise<boolean> {
178
+ if (!isIOS) return Promise.resolve(false);
179
+ return this.native.getDidOpenSettingsForNotification().then((value: boolean) => value);
180
+ }
181
+
182
+ getIsHeadless(): Promise<boolean> {
183
+ return this.native.getIsHeadless();
184
+ }
185
+
186
+ getToken(options?: { appName?: string; senderId?: string }): Promise<string> {
187
+ if (!isUndefined(options?.appName) && !isString(options?.appName)) {
188
+ throw new Error("getMessaging().getToken(*) 'appName' expected a string.");
189
+ }
190
+
191
+ if (!isUndefined(options?.senderId) && !isString(options?.senderId)) {
192
+ throw new Error("getMessaging().getToken(*) 'senderId' expected a string.");
193
+ }
194
+
195
+ const appName = options?.appName || this.app.name;
196
+ const senderId = options?.senderId || this.app.options.messagingSenderId;
197
+
198
+ return this.native.getToken(appName, senderId || '');
199
+ }
200
+
201
+ deleteToken(options?: { appName?: string; senderId?: string }): Promise<void> {
202
+ if (!isUndefined(options?.appName) && !isString(options?.appName)) {
203
+ throw new Error("getMessaging().deleteToken(*) 'appName' expected a string.");
204
+ }
205
+
206
+ if (!isUndefined(options?.senderId) && !isString(options?.senderId)) {
207
+ throw new Error("getMessaging().deleteToken(*) 'senderId' expected a string.");
208
+ }
209
+
210
+ const appName = options?.appName || this.app.name;
211
+ const senderId = options?.senderId || this.app.options.messagingSenderId;
212
+
213
+ return this.native.deleteToken(appName, senderId || '');
214
+ }
215
+
216
+ onMessage(listener: (message: RemoteMessage) => any): () => void {
217
+ if (!isFunction(listener)) {
218
+ throw new Error("getMessaging().onMessage(*) 'listener' expected a function.");
219
+ }
220
+
221
+ const subscription = this.emitter.addListener('messaging_message_received', listener);
222
+ return () => subscription.remove();
223
+ }
224
+
225
+ onNotificationOpenedApp(listener: (message: RemoteMessage) => any): () => void {
226
+ if (!isFunction(listener)) {
227
+ throw new Error("getMessaging().onNotificationOpenedApp(*) 'listener' expected a function.");
228
+ }
229
+
230
+ const subscription = this.emitter.addListener('messaging_notification_opened', listener);
231
+ return () => subscription.remove();
232
+ }
233
+
234
+ onTokenRefresh(listener: (token: string) => any): () => void {
235
+ if (!isFunction(listener)) {
236
+ throw new Error("getMessaging().onTokenRefresh(*) 'listener' expected a function.");
237
+ }
238
+
239
+ const subscription = this.emitter.addListener(
240
+ 'messaging_token_refresh',
241
+ (event: { token: string }) => {
242
+ const { token } = event;
243
+ listener(token);
244
+ },
245
+ );
246
+ return () => subscription.remove();
247
+ }
248
+
249
+ /**
250
+ * @platform ios
251
+ * @deprecated Use {@link https://github.com/zoontek/react-native-permissions react-native-permissions} or
252
+ * {@link https://docs.expo.dev/versions/latest/sdk/notifications/ expo-notifications} for notification permission
253
+ * requests instead. These APIs will be removed in a future major release.
254
+ * See {@link https://github.com/invertase/react-native-firebase/issues/6283 #6283}.
255
+ */
256
+ requestPermission(permissions?: IOSPermissions): Promise<AuthorizationStatusType> {
257
+ if (isAndroid) {
258
+ return Promise.resolve(AuthorizationStatus.AUTHORIZED);
259
+ }
260
+
261
+ const defaultPermissions: IOSPermissions = {
262
+ alert: true,
263
+ announcement: false,
264
+ badge: true,
265
+ carPlay: true,
266
+ provisional: false,
267
+ sound: true,
268
+ criticalAlert: false,
269
+ providesAppNotificationSettings: false,
270
+ };
271
+
272
+ if (!permissions) {
273
+ return this.native.requestPermission(defaultPermissions) as Promise<AuthorizationStatusType>;
274
+ }
275
+
276
+ if (!isObject(permissions)) {
277
+ throw new Error('getMessaging().requestPermission(*) expected an object value.');
278
+ }
279
+
280
+ Object.entries(permissions).forEach(([key, value]) => {
281
+ if (!hasOwnProperty(defaultPermissions, key)) {
282
+ throw new Error(
283
+ `getMessaging().requestPermission(*) unexpected key "${key}" provided to permissions object.`,
284
+ );
285
+ }
286
+
287
+ if (!isBoolean(value)) {
288
+ throw new Error(
289
+ `getMessaging().requestPermission(*) the permission "${key}" expected a boolean value.`,
290
+ );
291
+ }
292
+
293
+ (defaultPermissions as Record<string, boolean>)[key] = value;
294
+ });
295
+
296
+ return this.native.requestPermission(defaultPermissions) as Promise<AuthorizationStatusType>;
297
+ }
298
+
299
+ registerDeviceForRemoteMessages(): Promise<void> {
300
+ if (isAndroid) {
301
+ return Promise.resolve();
302
+ }
303
+
304
+ const autoRegister = this.firebaseJson['messaging_ios_auto_register_for_remote_messages'];
305
+ if (autoRegister === undefined || autoRegister === true) {
306
+ // eslint-disable-next-line no-console
307
+ console.warn(
308
+ `Usage of "registerDeviceForRemoteMessages()" is not required. You only need to register if auto-registration is disabled in your 'firebase.json' configuration file via the 'messaging_ios_auto_register_for_remote_messages' property.`,
309
+ );
310
+ }
311
+
312
+ this._isRegisteredForRemoteNotifications = true;
313
+ return this.native.registerForRemoteNotifications();
314
+ }
315
+
316
+ /**
317
+ * @platform ios
318
+ */
319
+ unregisterDeviceForRemoteMessages(): Promise<void> {
320
+ if (isAndroid) {
321
+ return Promise.resolve();
322
+ }
323
+ this._isRegisteredForRemoteNotifications = false;
324
+ return this.native.unregisterForRemoteNotifications();
325
+ }
326
+
327
+ /**
328
+ * @platform ios
329
+ */
330
+ getAPNSToken(): Promise<string | null> {
331
+ if (isAndroid) {
332
+ return Promise.resolve(null);
333
+ }
334
+ return this.native.getAPNSToken();
335
+ }
336
+
337
+ /**
338
+ * @platform ios
339
+ */
340
+ setAPNSToken(token: string, type?: string): Promise<void> {
341
+ if (isUndefined(token) || !isString(token)) {
342
+ throw new Error("getMessaging().setAPNSToken(*) 'token' expected a string value.");
343
+ }
344
+
345
+ if (!isUndefined(type) && (!isString(type) || !['prod', 'sandbox', 'unknown'].includes(type))) {
346
+ throw new Error(
347
+ "getMessaging().setAPNSToken(*) 'type' expected one of 'prod', 'sandbox', or 'unknown'.",
348
+ );
349
+ }
350
+
351
+ if (isAndroid) {
352
+ return Promise.resolve();
353
+ }
354
+
355
+ return this.native.setAPNSToken(token, type);
356
+ }
357
+
358
+ /**
359
+ * @deprecated Use {@link https://github.com/zoontek/react-native-permissions react-native-permissions} or
360
+ * {@link https://docs.expo.dev/versions/latest/sdk/notifications/ expo-notifications} for notification permission
361
+ * requests instead. These APIs will be removed in a future major release.
362
+ * See {@link https://github.com/invertase/react-native-firebase/issues/6283 #6283}.
363
+ */
364
+ hasPermission(): Promise<AuthorizationStatusType> {
365
+ return this.native.hasPermission() as Promise<AuthorizationStatusType>;
366
+ }
367
+
368
+ onDeletedMessages(listener: () => void): () => void {
369
+ if (!isFunction(listener)) {
370
+ throw new Error("getMessaging().onDeletedMessages(*) 'listener' expected a function.");
371
+ }
372
+
373
+ const subscription = this.emitter.addListener('messaging_message_deleted', listener);
374
+ return () => subscription.remove();
375
+ }
376
+
377
+ onMessageSent(listener: (messageId: string) => any): () => void {
378
+ if (!isFunction(listener)) {
379
+ throw new Error("getMessaging().onMessageSent(*) 'listener' expected a function.");
380
+ }
381
+
382
+ const subscription = this.emitter.addListener('messaging_message_sent', listener);
383
+ return () => {
384
+ subscription.remove();
385
+ };
386
+ }
387
+
388
+ onSendError(
389
+ listener: (evt: { messageId: string; error: ReactNativeFirebase.NativeFirebaseError }) => any,
390
+ ): () => void {
391
+ if (!isFunction(listener)) {
392
+ throw new Error("getMessaging().onSendError(*) 'listener' expected a function.");
393
+ }
394
+
395
+ const subscription = this.emitter.addListener('messaging_message_send_error', listener);
396
+ return () => subscription.remove();
397
+ }
398
+
399
+ setBackgroundMessageHandler(handler: (message: RemoteMessage) => Promise<any>): void {
400
+ if (!isFunction(handler)) {
401
+ throw new Error(
402
+ "getMessaging().setBackgroundMessageHandler(*) 'handler' expected a function.",
403
+ );
404
+ }
405
+
406
+ backgroundMessageHandler = handler;
407
+ if (isIOS) {
408
+ this.native.signalBackgroundMessageHandlerSet();
409
+ }
410
+ }
411
+
412
+ setOpenSettingsForNotificationsHandler(handler: (message: RemoteMessage) => any): void {
413
+ if (!isIOS) {
414
+ return;
415
+ }
416
+
417
+ if (!isFunction(handler)) {
418
+ throw new Error(
419
+ "getMessaging().setOpenSettingsForNotificationsHandler(*) 'handler' expected a function.",
420
+ );
421
+ }
422
+
423
+ openSettingsForNotificationHandler = handler;
424
+ }
425
+
426
+ sendMessage(remoteMessage: RemoteMessage): Promise<void> {
427
+ if (isIOS) {
428
+ throw new Error(`getMessaging().sendMessage() is only supported on Android devices.`);
429
+ }
430
+ let options;
431
+ try {
432
+ const senderId = this.app.options.messagingSenderId;
433
+ if (!senderId) {
434
+ throw new Error("'messagingSenderId' is required in Firebase app options.");
435
+ }
436
+ options = remoteMessageOptions(senderId, remoteMessage);
437
+ } catch (e: unknown) {
438
+ const message = e instanceof Error ? e.message : String(e);
439
+ throw new Error(`getMessaging().sendMessage(*) ${message}.`);
440
+ }
441
+
442
+ return this.native.sendMessage(options as unknown as Record<string, unknown>);
443
+ }
444
+
445
+ subscribeToTopic(topic: string): Promise<void> {
446
+ if (!isString(topic)) {
447
+ throw new Error("getMessaging().subscribeToTopic(*) 'topic' expected a string value.");
448
+ }
449
+
450
+ if (topic.indexOf('/') > -1) {
451
+ throw new Error('getMessaging().subscribeToTopic(*) \'topic\' must not include "/".');
452
+ }
453
+
454
+ return this.native.subscribeToTopic(topic);
455
+ }
456
+
457
+ unsubscribeFromTopic(topic: string): Promise<void> {
458
+ if (!isString(topic)) {
459
+ throw new Error("getMessaging().unsubscribeFromTopic(*) 'topic' expected a string value.");
460
+ }
461
+
462
+ if (topic.indexOf('/') > -1) {
463
+ throw new Error('getMessaging().unsubscribeFromTopic(*) \'topic\' must not include "/".');
464
+ }
465
+
466
+ return this.native.unsubscribeFromTopic(topic);
467
+ }
468
+
469
+ setDeliveryMetricsExportToBigQuery(enabled: boolean): Promise<void> {
470
+ if (!isBoolean(enabled)) {
471
+ throw new Error(
472
+ "getMessaging().setDeliveryMetricsExportToBigQuery(*) 'enabled' expected a boolean value.",
473
+ );
474
+ }
475
+
476
+ this._isDeliveryMetricsExportToBigQueryEnabled = enabled;
477
+ return this.native.setDeliveryMetricsExportToBigQuery(enabled);
478
+ }
479
+
480
+ setNotificationDelegationEnabled(enabled: boolean): Promise<void> {
481
+ if (!isBoolean(enabled)) {
482
+ throw new Error(
483
+ "getMessaging().setNotificationDelegationEnabled(*) 'enabled' expected a boolean value.",
484
+ );
485
+ }
486
+
487
+ this._isNotificationDelegationEnabled = enabled;
488
+ if (isIOS) {
489
+ return Promise.resolve();
490
+ }
491
+
492
+ return this.native.setNotificationDelegationEnabled(enabled);
493
+ }
494
+
495
+ async isSupported(): Promise<boolean> {
496
+ if (isAndroid) {
497
+ // NewArch-AD-18 E6: cross-package Play Services availability via utils host.
498
+ const utilsNativeModule = getReactNativeModule(UTILS_NATIVE_MODULE);
499
+ if (!utilsNativeModule) {
500
+ return false;
501
+ }
502
+ const androidGetPlayServicesStatus = utilsNativeModule.androidGetPlayServicesStatus as
503
+ | (() => Promise<{ isAvailable?: boolean }>)
504
+ | undefined;
505
+ if (typeof androidGetPlayServicesStatus !== 'function') {
506
+ return false;
507
+ }
508
+ const playServicesAvailability = await androidGetPlayServicesStatus();
509
+ return playServicesAvailability?.isAvailable ?? false;
510
+ }
511
+ return true;
512
+ }
513
+ }
514
+
515
+ const config: ModuleConfig = {
516
+ namespace: 'messaging',
517
+ nativeModuleName,
518
+ nativeEvents: [
519
+ 'messaging_token_refresh',
520
+ 'messaging_message_sent',
521
+ 'messaging_message_deleted',
522
+ 'messaging_message_received',
523
+ 'messaging_message_send_error',
524
+ 'messaging_notification_opened',
525
+ ...(isIOS
526
+ ? ['messaging_message_received_background', 'messaging_settings_for_notification_opened']
527
+ : []),
528
+ ],
529
+ hasMultiAppSupport: false,
530
+ hasCustomUrlOrRegionSupport: false,
531
+ turboModule: true,
532
+ };
533
+
534
+ export const SDK_VERSION = version;
535
+
536
+ export { AuthorizationStatus, NotificationAndroidPriority, NotificationAndroidVisibility };
537
+
538
+ /**
539
+ * Returns the {@link Messaging} instance for the default or given {@link FirebaseApp}.
540
+ *
541
+ * @param app - The Firebase `FirebaseApp` to use. When omitted, the default app is used.
542
+ * @returns The Messaging service instance for that app.
543
+ */
544
+ export function getMessaging(app?: FirebaseApp): Messaging {
545
+ return getOrCreateModularInstance(FirebaseMessagingModule, config, app) as unknown as Messaging;
546
+ }
547
+
548
+ /**
549
+ * Removes access to an FCM token previously authorized by its scope.
550
+ */
551
+ export function deleteToken(
552
+ messaging: Messaging,
553
+ tokenOptions?: NativeTokenOptions,
554
+ ): Promise<void> {
555
+ return messaging.deleteToken(tokenOptions);
556
+ }
557
+
558
+ /**
559
+ * Returns an FCM token for this device.
560
+ */
561
+ export function getToken(
562
+ messaging: Messaging,
563
+ options?: GetTokenOptions & NativeTokenOptions,
564
+ ): Promise<string> {
565
+ return messaging.getToken(options);
566
+ }
567
+
568
+ /**
569
+ * Subscribes to foreground FCM messages.
570
+ *
571
+ * @remarks Event delivery uses the legacy native event proxy shared across RN Firebase modules
572
+ * (not yet migrated to Codegen TurboModule events). Behavior matches pre-v26 releases.
573
+ */
574
+ export function onMessage(
575
+ messaging: Messaging,
576
+ listener: (message: RemoteMessage) => any,
577
+ ): () => void {
578
+ return messaging.onMessage(listener);
579
+ }
580
+
581
+ /**
582
+ * When the user presses a notification displayed via FCM, this listener will be called if the app
583
+ * has opened from a background state.
584
+ *
585
+ * @remarks Event delivery uses the legacy native event proxy shared across RN Firebase modules
586
+ * (not yet migrated to Codegen TurboModule events). Behavior matches pre-v26 releases.
587
+ */
588
+ export function onNotificationOpenedApp(
589
+ messaging: Messaging,
590
+ listener: (message: RemoteMessage) => any,
591
+ ): () => void {
592
+ return messaging.onNotificationOpenedApp(listener);
593
+ }
594
+
595
+ /**
596
+ * Called when a new registration token is generated for the device.
597
+ *
598
+ * @remarks Event delivery uses the legacy native event proxy shared across RN Firebase modules
599
+ * (not yet migrated to Codegen TurboModule events). Behavior matches pre-v26 releases.
600
+ */
601
+ export function onTokenRefresh(messaging: Messaging, listener: (token: string) => any): () => void {
602
+ return messaging.onTokenRefresh(listener);
603
+ }
604
+
605
+ /**
606
+ * On iOS, messaging permission must be requested by the current application before messages can
607
+ * be received or sent.
608
+ *
609
+ * @deprecated Use {@link https://github.com/zoontek/react-native-permissions react-native-permissions} or
610
+ * {@link https://docs.expo.dev/versions/latest/sdk/notifications/ expo-notifications} for notification permission
611
+ * requests instead. These APIs will be removed in a future major release.
612
+ * See {@link https://github.com/invertase/react-native-firebase/issues/6283 #6283}.
613
+ */
614
+ export function requestPermission(
615
+ messaging: Messaging,
616
+ iosPermissions?: IOSPermissions,
617
+ ): Promise<AuthorizationStatusType> {
618
+ return messaging.requestPermission(iosPermissions);
619
+ }
620
+
621
+ /**
622
+ * Returns whether messaging auto initialization is enabled or disabled for the device.
623
+ */
624
+ export function isAutoInitEnabled(messaging: Messaging): boolean {
625
+ return messaging.isAutoInitEnabled;
626
+ }
627
+
628
+ /**
629
+ * Sets whether messaging auto initialization is enabled or disabled for the device.
630
+ */
631
+ export function setAutoInitEnabled(messaging: Messaging, enabled: boolean): Promise<void> {
632
+ return messaging.setAutoInitEnabled(enabled);
633
+ }
634
+
635
+ /**
636
+ * When a notification from FCM has triggered the application to open from a quit state,
637
+ * this method will return a `RemoteMessage` containing the notification data, or `null`.
638
+ */
639
+ export function getInitialNotification(messaging: Messaging): Promise<RemoteMessage | null> {
640
+ return messaging.getInitialNotification();
641
+ }
642
+
643
+ /**
644
+ * When the app is opened from iOS notifications settings from a quit state,
645
+ * this method will return `true` or `false` if the app was opened via another method.
646
+ */
647
+ export function getDidOpenSettingsForNotification(messaging: Messaging): Promise<boolean> {
648
+ return messaging.getDidOpenSettingsForNotification();
649
+ }
650
+
651
+ /**
652
+ * Returns whether the root view is headless or not.
653
+ */
654
+ export function getIsHeadless(messaging: Messaging): Promise<boolean> {
655
+ return messaging.getIsHeadless();
656
+ }
657
+
658
+ /**
659
+ * On iOS, if your app wants to receive remote messages from FCM (via APNs), you must explicitly register
660
+ * with APNs if auto-registration has been disabled.
661
+ *
662
+ * On ARM64 iOS Simulator, native registration skips UIKit `registerForRemoteNotifications`
663
+ * (main-thread wedge risk) and may reject with `messaging/registration-timeout` after ~10s.
664
+ * Use a physical device for real APNs tokens. A second overlapping call rejects the prior
665
+ * attempt with `messaging/registration-superseded`. See migrating-to-v26 Cloud Messaging —
666
+ * iOS APNs registration.
667
+ */
668
+ export function registerDeviceForRemoteMessages(messaging: Messaging): Promise<void> {
669
+ return messaging.registerDeviceForRemoteMessages();
670
+ }
671
+
672
+ /**
673
+ * Returns a boolean value whether the user has registered for remote notifications via
674
+ * `registerDeviceForRemoteMessages()`.
675
+ */
676
+ export function isDeviceRegisteredForRemoteMessages(messaging: Messaging): boolean {
677
+ return messaging.isDeviceRegisteredForRemoteMessages;
678
+ }
679
+
680
+ /**
681
+ * Unregisters the app from receiving remote notifications.
682
+ */
683
+ export function unregisterDeviceForRemoteMessages(messaging: Messaging): Promise<void> {
684
+ return messaging.unregisterDeviceForRemoteMessages();
685
+ }
686
+
687
+ /**
688
+ * Returns the APNs device token on iOS.
689
+ *
690
+ * @remarks **iOS only.** Returns `null` when no token is available. There is no firebase-js-sdk
691
+ * modular equivalent — web push uses a different token lifecycle.
692
+ */
693
+ export function getAPNSToken(messaging: Messaging): Promise<string | null> {
694
+ return messaging.getAPNSToken();
695
+ }
696
+
697
+ /**
698
+ * Sets the APNs device token received by the application delegate.
699
+ *
700
+ * @remarks **iOS only.** `type` must be `'prod'`, `'sandbox'`, or `'unknown'`.
701
+ */
702
+ export function setAPNSToken(messaging: Messaging, token: string, type?: string): Promise<void> {
703
+ return messaging.setAPNSToken(token, type);
704
+ }
705
+
706
+ /**
707
+ * Returns a `AuthorizationStatus` as to whether the user has messaging permission for this app.
708
+ *
709
+ * @deprecated Use {@link https://github.com/zoontek/react-native-permissions react-native-permissions} or
710
+ * {@link https://docs.expo.dev/versions/latest/sdk/notifications/ expo-notifications} for notification permission
711
+ * requests instead. These APIs will be removed in a future major release.
712
+ * See {@link https://github.com/invertase/react-native-firebase/issues/6283 #6283}.
713
+ */
714
+ export function hasPermission(messaging: Messaging): Promise<AuthorizationStatusType> {
715
+ return messaging.hasPermission();
716
+ }
717
+
718
+ /**
719
+ * Called when the FCM server deletes pending messages.
720
+ *
721
+ * @remarks Event delivery uses the legacy native event proxy shared across RN Firebase modules
722
+ * (not yet migrated to Codegen TurboModule events). Behavior matches pre-v26 releases.
723
+ */
724
+ export function onDeletedMessages(messaging: Messaging, listener: () => void): () => void {
725
+ return messaging.onDeletedMessages(listener);
726
+ }
727
+
728
+ /**
729
+ * When sending a `RemoteMessage`, this listener is called when the message has been sent to FCM.
730
+ */
731
+ export function onMessageSent(
732
+ messaging: Messaging,
733
+ listener: (messageId: string) => any,
734
+ ): () => void {
735
+ return messaging.onMessageSent(listener);
736
+ }
737
+
738
+ /**
739
+ * When sending a `RemoteMessage`, this listener is called when an error is thrown and the
740
+ * message could not be sent.
741
+ *
742
+ * @remarks Event delivery uses the legacy native event proxy shared across RN Firebase modules
743
+ * (not yet migrated to Codegen TurboModule events). Behavior matches pre-v26 releases.
744
+ */
745
+ export function onSendError(
746
+ messaging: Messaging,
747
+ listener: (evt: SendErrorEvent) => any,
748
+ ): () => void {
749
+ return messaging.onSendError(listener);
750
+ }
751
+
752
+ /**
753
+ * Set a message handler function which is called when the app is in the background or terminated.
754
+ *
755
+ * @remarks Event delivery uses the legacy native event proxy shared across RN Firebase modules
756
+ * (not yet migrated to Codegen TurboModule events). Behavior matches pre-v26 releases.
757
+ */
758
+ export function setBackgroundMessageHandler(
759
+ messaging: Messaging,
760
+ handler: (message: RemoteMessage) => Promise<any>,
761
+ ): void {
762
+ return messaging.setBackgroundMessageHandler(handler);
763
+ }
764
+
765
+ /**
766
+ * Set a handler function which is called when the `${App Name} notifications settings`
767
+ * link in iOS settings is clicked.
768
+ */
769
+ export function setOpenSettingsForNotificationsHandler(
770
+ messaging: Messaging,
771
+ handler: (message: RemoteMessage) => any,
772
+ ): void {
773
+ return messaging.setOpenSettingsForNotificationsHandler(handler);
774
+ }
775
+
776
+ /**
777
+ * Send a new `RemoteMessage` to the FCM server.
778
+ */
779
+ export function sendMessage(messaging: Messaging, message: RemoteMessage): Promise<void> {
780
+ return messaging.sendMessage(message);
781
+ }
782
+
783
+ /**
784
+ * Apps can subscribe to a topic, which allows the FCM server to send targeted messages to only those
785
+ * devices subscribed to that topic.
786
+ */
787
+ export function subscribeToTopic(messaging: Messaging, topic: string): Promise<void> {
788
+ return messaging.subscribeToTopic(topic);
789
+ }
790
+
791
+ /**
792
+ * Unsubscribe the device from a topic.
793
+ */
794
+ export function unsubscribeFromTopic(messaging: Messaging, topic: string): Promise<void> {
795
+ return messaging.unsubscribeFromTopic(topic);
796
+ }
797
+
798
+ /**
799
+ * Returns a boolean whether message delivery metrics are exported to BigQuery.
800
+ */
801
+ export function isDeliveryMetricsExportToBigQueryEnabled(messaging: Messaging): boolean {
802
+ return messaging.isDeliveryMetricsExportToBigQueryEnabled;
803
+ }
804
+
805
+ /**
806
+ * Returns a boolean whether message delegation is enabled. Android only, always returns false on iOS.
807
+ */
808
+ export function isNotificationDelegationEnabled(messaging: Messaging): boolean {
809
+ return messaging.isNotificationDelegationEnabled;
810
+ }
811
+
812
+ /**
813
+ * Sets whether message notification delegation is enabled or disabled.
814
+ */
815
+ export function setNotificationDelegationEnabled(
816
+ messaging: Messaging,
817
+ enabled: boolean,
818
+ ): Promise<void> {
819
+ return messaging.setNotificationDelegationEnabled(enabled);
820
+ }
821
+
822
+ /**
823
+ * Checks if all required APIs exist in the browser.
824
+ */
825
+ export function isSupported(messaging: Messaging): Promise<boolean> {
826
+ return messaging.isSupported();
827
+ }
828
+
829
+ /**
830
+ * Sets whether message delivery metrics are exported to BigQuery is enabled or disabled.
831
+ */
832
+ export function experimentalSetDeliveryMetricsExportedToBigQueryEnabled(
833
+ messaging: Messaging,
834
+ enabled: boolean,
835
+ ): Promise<void> {
836
+ return messaging.setDeliveryMetricsExportToBigQuery(enabled);
837
+ }
838
+
19
839
  export type {
20
840
  Messaging,
21
841
  RemoteMessage,
@@ -27,18 +847,4 @@ export type {
27
847
  NotificationIOSCriticalSound,
28
848
  IOSPermissions,
29
849
  SendErrorEvent,
30
- FirebaseMessagingTypes,
31
850
  } from './types/messaging';
32
-
33
- export {
34
- AuthorizationStatus,
35
- NotificationAndroidPriority,
36
- NotificationAndroidVisibility,
37
- } from './statics';
38
-
39
- // Export modular API functions
40
- export * from './modular';
41
-
42
- // Export namespaced API
43
- export * from './namespaced';
44
- export { default } from './namespaced';