@react-native-firebase/messaging 20.4.0 → 21.0.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.
- package/CHANGELOG.md +11 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingReceiver.java +4 -0
- package/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m +4 -4
- package/ios/RNFBMessaging/RNFBMessaging+UNUserNotificationCenter.m +1 -3
- package/ios/RNFBMessaging/RNFBMessagingModule.m +98 -146
- package/lib/version.js +1 -1
- package/package.json +4 -4
- package/plugin/build/android/setupFirebaseNotifationIcon.js +2 -2
- package/plugin/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md
CHANGED
@@ -3,6 +3,17 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
5
5
|
|
6
|
+
## [21.0.0](https://github.com/invertase/react-native-firebase/compare/v20.5.0...v21.0.0) (2024-09-26)
|
7
|
+
|
8
|
+
**Note:** Version bump only for package @react-native-firebase/messaging
|
9
|
+
|
10
|
+
## [20.5.0](https://github.com/invertase/react-native-firebase/compare/v20.4.0...v20.5.0) (2024-09-11)
|
11
|
+
|
12
|
+
### Bug Fixes
|
13
|
+
|
14
|
+
- **messaging, android:** handle nullable broadcast intent ([#7893](https://github.com/invertase/react-native-firebase/issues/7893)) ([#7960](https://github.com/invertase/react-native-firebase/issues/7960)) ([c1ac022](https://github.com/invertase/react-native-firebase/commit/c1ac022e4e9d3effb2f0fb3404ad375d9fcbe4b6))
|
15
|
+
- **messaging, ios:** fixed isHeadless for react-native-navigation ([#7868](https://github.com/invertase/react-native-firebase/issues/7868)) ([3875cc6](https://github.com/invertase/react-native-firebase/commit/3875cc6077e5fd6b35e201356aca632e43a2e301))
|
16
|
+
|
6
17
|
## [20.4.0](https://github.com/invertase/react-native-firebase/compare/v20.3.0...v20.4.0) (2024-08-13)
|
7
18
|
|
8
19
|
**Note:** Version bump only for package @react-native-firebase/messaging
|
@@ -22,6 +22,10 @@ public class ReactNativeFirebaseMessagingReceiver extends BroadcastReceiver {
|
|
22
22
|
if (ReactNativeFirebaseApp.getApplicationContext() == null) {
|
23
23
|
ReactNativeFirebaseApp.setApplicationContext(context.getApplicationContext());
|
24
24
|
}
|
25
|
+
if (intent.getExtras() == null) {
|
26
|
+
Log.e(TAG, "broadcast intent received with no extras");
|
27
|
+
return;
|
28
|
+
}
|
25
29
|
RemoteMessage remoteMessage = new RemoteMessage(intent.getExtras());
|
26
30
|
ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance();
|
27
31
|
|
@@ -96,8 +96,8 @@
|
|
96
96
|
|
97
97
|
if (notification.userInfo[UIApplicationLaunchOptionsRemoteNotificationKey]) {
|
98
98
|
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
|
99
|
+
isHeadless = YES;
|
99
100
|
if (rctRootView != nil) {
|
100
|
-
isHeadless = YES;
|
101
101
|
NSMutableDictionary *appPropertiesDict = rctRootView.appProperties != nil
|
102
102
|
? [rctRootView.appProperties mutableCopy]
|
103
103
|
: [NSMutableDictionary dictionary];
|
@@ -120,8 +120,8 @@
|
|
120
120
|
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
121
121
|
// #endif
|
122
122
|
} else {
|
123
|
+
isHeadless = NO;
|
123
124
|
if (rctRootView != nil) {
|
124
|
-
isHeadless = NO;
|
125
125
|
NSMutableDictionary *appPropertiesDict = rctRootView.appProperties != nil
|
126
126
|
? [rctRootView.appProperties mutableCopy]
|
127
127
|
: [NSMutableDictionary dictionary];
|
@@ -133,8 +133,8 @@
|
|
133
133
|
}
|
134
134
|
}
|
135
135
|
} else {
|
136
|
+
isHeadless = NO;
|
136
137
|
if (rctRootView != nil) {
|
137
|
-
isHeadless = NO;
|
138
138
|
NSMutableDictionary *appPropertiesDict = rctRootView.appProperties != nil
|
139
139
|
? [rctRootView.appProperties mutableCopy]
|
140
140
|
: [NSMutableDictionary dictionary];
|
@@ -148,6 +148,7 @@
|
|
148
148
|
}
|
149
149
|
|
150
150
|
- (void)application_onDidEnterForeground {
|
151
|
+
isHeadless = NO;
|
151
152
|
if ([UIApplication sharedApplication].delegate != nil &&
|
152
153
|
[UIApplication sharedApplication].delegate.window != nil &&
|
153
154
|
[UIApplication sharedApplication].delegate.window.rootViewController != nil &&
|
@@ -160,7 +161,6 @@
|
|
160
161
|
if (rctRootView.appProperties != nil &&
|
161
162
|
[rctRootView.appProperties[@"isHeadless"] isEqual:@(YES)]) {
|
162
163
|
NSMutableDictionary *appPropertiesDict = [rctRootView.appProperties mutableCopy];
|
163
|
-
isHeadless = NO;
|
164
164
|
if ([appPropertiesDict objectForKey:@"isHeadless"] != nil &&
|
165
165
|
[appPropertiesDict[@"isHeadless"] isEqual:@([RCTConvert BOOL:@(YES)])]) {
|
166
166
|
appPropertiesDict[@"isHeadless"] = @([RCTConvert BOOL:@(isHeadless)]);
|
@@ -172,9 +172,7 @@ struct {
|
|
172
172
|
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
|
173
173
|
openSettingsForNotification:(nullable UNNotification *)notification {
|
174
174
|
if (_originalDelegate != nil && originalDelegateRespondsTo.openSettingsForNotification) {
|
175
|
-
|
176
|
-
[_originalDelegate userNotificationCenter:center openSettingsForNotification:notification];
|
177
|
-
}
|
175
|
+
[_originalDelegate userNotificationCenter:center openSettingsForNotification:notification];
|
178
176
|
} else {
|
179
177
|
NSDictionary *notificationDict = [RNFBMessagingSerializer notificationToDict:notification];
|
180
178
|
[[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_settings_for_notification_opened"
|
@@ -233,78 +233,58 @@ RCT_EXPORT_METHOD(requestPermission
|
|
233
233
|
return;
|
234
234
|
}
|
235
235
|
|
236
|
-
|
237
|
-
UNAuthorizationOptions options = UNAuthorizationOptionNone;
|
236
|
+
UNAuthorizationOptions options = UNAuthorizationOptionNone;
|
238
237
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
if ([permissions[@"badge"] isEqual:@(YES)]) {
|
244
|
-
options |= UNAuthorizationOptionBadge;
|
245
|
-
}
|
238
|
+
if ([permissions[@"alert"] isEqual:@(YES)]) {
|
239
|
+
options |= UNAuthorizationOptionAlert;
|
240
|
+
}
|
246
241
|
|
247
|
-
|
248
|
-
|
249
|
-
|
242
|
+
if ([permissions[@"badge"] isEqual:@(YES)]) {
|
243
|
+
options |= UNAuthorizationOptionBadge;
|
244
|
+
}
|
250
245
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
}
|
255
|
-
}
|
246
|
+
if ([permissions[@"sound"] isEqual:@(YES)]) {
|
247
|
+
options |= UNAuthorizationOptionSound;
|
248
|
+
}
|
256
249
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
}
|
261
|
-
}
|
250
|
+
if ([permissions[@"criticalAlert"] isEqual:@(YES)]) {
|
251
|
+
options |= UNAuthorizationOptionCriticalAlert;
|
252
|
+
}
|
262
253
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
options |= UNAuthorizationOptionAnnouncement;
|
267
|
-
#endif
|
268
|
-
}
|
269
|
-
}
|
254
|
+
if ([permissions[@"provisional"] isEqual:@(YES)]) {
|
255
|
+
options |= UNAuthorizationOptionProvisional;
|
256
|
+
}
|
270
257
|
|
271
|
-
|
272
|
-
|
273
|
-
|
258
|
+
if ([permissions[@"announcement"] isEqual:@(YES)]) {
|
259
|
+
options |= UNAuthorizationOptionAnnouncement;
|
260
|
+
}
|
274
261
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
}
|
279
|
-
}
|
262
|
+
if ([permissions[@"carPlay"] isEqual:@(YES)]) {
|
263
|
+
options |= UNAuthorizationOptionCarPlay;
|
264
|
+
}
|
280
265
|
|
281
|
-
|
282
|
-
|
283
|
-
completionHandler:^(BOOL granted, NSError *_Nullable error) {
|
284
|
-
if (error) {
|
285
|
-
[RNFBSharedUtils rejectPromiseWithNSError:reject error:error];
|
286
|
-
} else {
|
287
|
-
// if we do not attempt to register immediately, registration fails
|
288
|
-
// later unknown reason why, but this was the only difference between
|
289
|
-
// using a react-native-permissions vs built-in permissions request in
|
290
|
-
// a sequence of "request permissions" --> "register for messages" you
|
291
|
-
// only want to request permission if you want to register for
|
292
|
-
// messages, so we register directly now - see #7272
|
293
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
294
|
-
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
295
|
-
});
|
296
|
-
[self hasPermission:resolve:reject];
|
297
|
-
}
|
298
|
-
}];
|
299
|
-
} else {
|
300
|
-
[RNFBSharedUtils
|
301
|
-
rejectPromiseWithUserInfo:reject
|
302
|
-
userInfo:[@{
|
303
|
-
@"code" : @"unsupported-platform-version",
|
304
|
-
@"message" : @"requestPermission call failed; minimum supported version "
|
305
|
-
@"requirement not met (iOS 10)."
|
306
|
-
} mutableCopy]];
|
266
|
+
if ([permissions[@"providesAppNotificationSettings"] isEqual:@(YES)]) {
|
267
|
+
options |= UNAuthorizationOptionProvidesAppNotificationSettings;
|
307
268
|
}
|
269
|
+
|
270
|
+
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
271
|
+
[center requestAuthorizationWithOptions:options
|
272
|
+
completionHandler:^(BOOL granted, NSError *_Nullable error) {
|
273
|
+
if (error) {
|
274
|
+
[RNFBSharedUtils rejectPromiseWithNSError:reject error:error];
|
275
|
+
} else {
|
276
|
+
// if we do not attempt to register immediately, registration fails
|
277
|
+
// later unknown reason why, but this was the only difference between
|
278
|
+
// using a react-native-permissions vs built-in permissions request in
|
279
|
+
// a sequence of "request permissions" --> "register for messages" you
|
280
|
+
// only want to request permission if you want to register for
|
281
|
+
// messages, so we register directly now - see #7272
|
282
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
283
|
+
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
284
|
+
});
|
285
|
+
[self hasPermission:resolve:reject];
|
286
|
+
}
|
287
|
+
}];
|
308
288
|
}
|
309
289
|
|
310
290
|
RCT_EXPORT_METHOD(registerForRemoteNotifications
|
@@ -320,59 +300,45 @@ RCT_EXPORT_METHOD(registerForRemoteNotifications
|
|
320
300
|
DLog(@"RNFBMessaging registerForRemoteNotifications ARM64 Simulator detected, attempting real "
|
321
301
|
@"registration. macOS13+ / iOS16+ / M1 mac required or will timeout.")
|
322
302
|
#endif
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
if ([UIApplication sharedApplication].isRegisteredForRemoteNotifications == YES) {
|
328
|
-
DLog(@"RNFBMessaging registerForRemoteNotifications - already registered.");
|
329
|
-
resolve(@([RCTConvert BOOL:@(YES)]));
|
330
|
-
return;
|
331
|
-
} else {
|
332
|
-
[[RNFBMessagingAppDelegate sharedInstance] setPromiseResolve:resolve andPromiseReject:reject];
|
333
|
-
}
|
334
|
-
|
335
|
-
// Apple docs recommend that registerForRemoteNotifications is always called on app start
|
336
|
-
// regardless of current status
|
337
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
338
|
-
// Sometimes the registration never completes, which deserves separate attention in other
|
339
|
-
// areas. This area should protect itself against hanging forever regardless. Just in case,
|
340
|
-
// check in after a delay and cleanup if required
|
341
|
-
dispatch_after(
|
342
|
-
dispatch_time(DISPATCH_TIME_NOW, 10.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
343
|
-
if ([RNFBMessagingAppDelegate sharedInstance].registerPromiseResolver != nil) {
|
344
|
-
// if we got here and resolve/reject are still set, unset, log failure, reject
|
345
|
-
DLog(@"RNFBMessaging dispatch_after block: we appear to have timed out. Rejecting");
|
346
|
-
[[RNFBMessagingAppDelegate sharedInstance] setPromiseResolve:nil
|
347
|
-
andPromiseReject:nil];
|
348
|
-
|
349
|
-
[RNFBSharedUtils
|
350
|
-
rejectPromiseWithUserInfo:reject
|
351
|
-
userInfo:[@{
|
352
|
-
@"code" : @"unknown-error",
|
353
|
-
@"message" :
|
354
|
-
@"registerDeviceForRemoteMessages requested but "
|
355
|
-
@"system did not respond. Possibly missing permission."
|
356
|
-
} mutableCopy]];
|
357
|
-
return;
|
358
|
-
} else {
|
359
|
-
DLog(@"RNFBMessaging dispatch_after: registerDeviceForRemoteMessages handled.");
|
360
|
-
return;
|
361
|
-
}
|
362
|
-
});
|
363
|
-
|
364
|
-
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
365
|
-
});
|
303
|
+
if ([UIApplication sharedApplication].isRegisteredForRemoteNotifications == YES) {
|
304
|
+
DLog(@"RNFBMessaging registerForRemoteNotifications - already registered.");
|
305
|
+
resolve(@([RCTConvert BOOL:@(YES)]));
|
306
|
+
return;
|
366
307
|
}
|
367
308
|
else {
|
368
|
-
[
|
369
|
-
rejectPromiseWithUserInfo:reject
|
370
|
-
userInfo:[@{
|
371
|
-
@"code" : @"unsupported-platform-version",
|
372
|
-
@"message" : @"registerDeviceForRemoteMessages call failed; minimum "
|
373
|
-
@"supported version requirement not met (iOS 10)."
|
374
|
-
} mutableCopy]];
|
309
|
+
[[RNFBMessagingAppDelegate sharedInstance] setPromiseResolve:resolve andPromiseReject:reject];
|
375
310
|
}
|
311
|
+
|
312
|
+
// Apple docs recommend that registerForRemoteNotifications is always called on app start
|
313
|
+
// regardless of current status
|
314
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
315
|
+
// Sometimes the registration never completes, which deserves separate attention in other
|
316
|
+
// areas. This area should protect itself against hanging forever regardless. Just in case,
|
317
|
+
// check in after a delay and cleanup if required
|
318
|
+
dispatch_after(
|
319
|
+
dispatch_time(DISPATCH_TIME_NOW, 10.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
320
|
+
if ([RNFBMessagingAppDelegate sharedInstance].registerPromiseResolver != nil) {
|
321
|
+
// if we got here and resolve/reject are still set, unset, log failure, reject
|
322
|
+
DLog(@"RNFBMessaging dispatch_after block: we appear to have timed out. Rejecting");
|
323
|
+
[[RNFBMessagingAppDelegate sharedInstance] setPromiseResolve:nil andPromiseReject:nil];
|
324
|
+
|
325
|
+
[RNFBSharedUtils
|
326
|
+
rejectPromiseWithUserInfo:reject
|
327
|
+
userInfo:[@{
|
328
|
+
@"code" : @"unknown-error",
|
329
|
+
@"message" :
|
330
|
+
@"registerDeviceForRemoteMessages requested but "
|
331
|
+
@"system did not respond. Possibly missing permission."
|
332
|
+
} mutableCopy]];
|
333
|
+
return;
|
334
|
+
} else {
|
335
|
+
DLog(@"RNFBMessaging dispatch_after: registerDeviceForRemoteMessages handled.");
|
336
|
+
return;
|
337
|
+
}
|
338
|
+
});
|
339
|
+
|
340
|
+
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
341
|
+
});
|
376
342
|
}
|
377
343
|
|
378
344
|
RCT_EXPORT_METHOD(unregisterForRemoteNotifications
|
@@ -383,41 +349,27 @@ RCT_EXPORT_METHOD(unregisterForRemoteNotifications
|
|
383
349
|
}
|
384
350
|
|
385
351
|
RCT_EXPORT_METHOD(hasPermission : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) {
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
352
|
+
[[UNUserNotificationCenter currentNotificationCenter]
|
353
|
+
getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *_Nonnull settings) {
|
354
|
+
NSNumber *authorizedStatus = @-1;
|
355
|
+
if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
|
356
|
+
authorizedStatus = @-1;
|
357
|
+
} else if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
|
358
|
+
authorizedStatus = @0;
|
359
|
+
} else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
|
360
|
+
authorizedStatus = @1;
|
361
|
+
} else if (settings.authorizationStatus == UNAuthorizationStatusProvisional) {
|
362
|
+
authorizedStatus = @2;
|
363
|
+
}
|
364
|
+
|
365
|
+
if (@available(iOS 14.0, macCatalyst 14.0, *)) {
|
366
|
+
if (settings.authorizationStatus == UNAuthorizationStatusEphemeral) {
|
367
|
+
authorizedStatus = @3;
|
402
368
|
}
|
369
|
+
}
|
403
370
|
|
404
|
-
|
405
|
-
|
406
|
-
authorizedStatus = @3;
|
407
|
-
}
|
408
|
-
}
|
409
|
-
|
410
|
-
resolve(authorizedStatus);
|
411
|
-
}];
|
412
|
-
} else {
|
413
|
-
[RNFBSharedUtils
|
414
|
-
rejectPromiseWithUserInfo:reject
|
415
|
-
userInfo:[@{
|
416
|
-
@"code" : @"unsupported-platform-version",
|
417
|
-
@"message" : @"hasPermission call failed; minimum supported version "
|
418
|
-
@"requirement not met (iOS 10)."
|
419
|
-
} mutableCopy]];
|
420
|
-
}
|
371
|
+
resolve(authorizedStatus);
|
372
|
+
}];
|
421
373
|
}
|
422
374
|
|
423
375
|
RCT_EXPORT_METHOD(subscribeToTopic
|
package/lib/version.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
// Generated by genversion.
|
2
|
-
module.exports = '
|
2
|
+
module.exports = '21.0.0';
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@react-native-firebase/messaging",
|
3
|
-
"version": "
|
3
|
+
"version": "21.0.0",
|
4
4
|
"author": "Invertase <oss@invertase.io> (http://invertase.io)",
|
5
5
|
"description": "React Native Firebase - React Native Firebase provides native integration of Firebase Cloud Messaging (FCM) for both Android & iOS. FCM is a cost free service, allowing for server-device and device-device communication. The React Native Firebase Messaging module provides a simple JavaScript API to interact with FCM.",
|
6
6
|
"main": "lib/index.js",
|
@@ -24,11 +24,11 @@
|
|
24
24
|
"messaging"
|
25
25
|
],
|
26
26
|
"peerDependencies": {
|
27
|
-
"@react-native-firebase/app": "
|
27
|
+
"@react-native-firebase/app": "21.0.0",
|
28
28
|
"expo": ">=47.0.0"
|
29
29
|
},
|
30
30
|
"devDependencies": {
|
31
|
-
"expo": "^50.0.
|
31
|
+
"expo": "^50.0.21"
|
32
32
|
},
|
33
33
|
"peerDependenciesMeta": {
|
34
34
|
"expo": {
|
@@ -38,5 +38,5 @@
|
|
38
38
|
"publishConfig": {
|
39
39
|
"access": "public"
|
40
40
|
},
|
41
|
-
"gitHead": "
|
41
|
+
"gitHead": "6965c40db30a832a21c3f9a93f6e5df36f137461"
|
42
42
|
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.withExpoPluginFirebaseNotification = void 0;
|
4
|
+
exports.setFireBaseMessagingAndroidManifest = setFireBaseMessagingAndroidManifest;
|
4
5
|
const config_plugins_1 = require("@expo/config-plugins");
|
5
6
|
/**
|
6
7
|
* Determine whether a ManifestApplication has an attribute.
|
@@ -59,4 +60,3 @@ function setFireBaseMessagingAndroidManifest(config, application) {
|
|
59
60
|
}
|
60
61
|
return application;
|
61
62
|
}
|
62
|
-
exports.setFireBaseMessagingAndroidManifest = setFireBaseMessagingAndroidManifest;
|
@@ -0,0 +1 @@
|
|
1
|
+
{"root":["./src/index.ts","./src/android/index.ts","./src/android/setupFirebaseNotifationIcon.ts"],"version":"5.6.2"}
|