@react-native-firebase/messaging 23.8.0 → 23.8.2
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 +1197 -0
- package/RNFBMessaging.podspec +50 -0
- package/android/.editorconfig +10 -0
- package/android/build.gradle +149 -0
- package/android/lint.xml +5 -0
- package/android/settings.gradle +1 -0
- package/android/src/main/AndroidManifest.xml +43 -0
- package/android/src/main/java/io/invertase/firebase/messaging/JsonConvert.java +127 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingHeadlessService.java +30 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingModule.java +332 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingPackage.java +41 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingReceiver.java +66 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingSerializer.java +225 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingService.java +37 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingStore.java +15 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingStoreHelper.java +23 -0
- package/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingStoreImpl.java +97 -0
- package/android/src/main/res/values/colors.xml +143 -0
- package/app.plugin.js +1 -0
- package/dist/commonjs/version.js +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/commonjs/lib/namespaced.d.ts +1 -1
- package/dist/typescript/commonjs/lib/version.d.ts +1 -1
- package/dist/typescript/module/lib/namespaced.d.ts +1 -1
- package/dist/typescript/module/lib/version.d.ts +1 -1
- package/ios/RNFBMessaging/RNFBMessaging+AppDelegate.h +54 -0
- package/ios/RNFBMessaging/RNFBMessaging+AppDelegate.m +251 -0
- package/ios/RNFBMessaging/RNFBMessaging+FIRMessagingDelegate.h +31 -0
- package/ios/RNFBMessaging/RNFBMessaging+FIRMessagingDelegate.m +70 -0
- package/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.h +29 -0
- package/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m +173 -0
- package/ios/RNFBMessaging/RNFBMessaging+UNUserNotificationCenter.h +37 -0
- package/ios/RNFBMessaging/RNFBMessaging+UNUserNotificationCenter.m +185 -0
- package/ios/RNFBMessaging/RNFBMessagingModule.h +26 -0
- package/ios/RNFBMessaging/RNFBMessagingModule.m +431 -0
- package/ios/RNFBMessaging/RNFBMessagingSerializer.h +32 -0
- package/ios/RNFBMessaging/RNFBMessagingSerializer.m +235 -0
- package/ios/RNFBMessaging.xcodeproj/project.pbxproj +384 -0
- package/ios/RNFBMessaging.xcodeproj/xcshareddata/IDETemplateMacros.plist +24 -0
- package/lib/version.ts +1 -1
- package/package.json +5 -15
- package/plugin/build/android/index.d.ts +2 -0
- package/plugin/build/android/index.js +5 -0
- package/plugin/build/android/setupFirebaseNotifationIcon.d.ts +8 -0
- package/plugin/build/android/setupFirebaseNotifationIcon.js +62 -0
- package/plugin/build/index.d.ts +3 -0
- package/plugin/build/index.js +16 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#import <RNFBApp/RNFBRCTEventEmitter.h>
|
|
19
|
+
|
|
20
|
+
#import "RNFBJSON.h"
|
|
21
|
+
#import "RNFBMessaging+UNUserNotificationCenter.h"
|
|
22
|
+
#import "RNFBMessagingSerializer.h"
|
|
23
|
+
|
|
24
|
+
@implementation RNFBMessagingUNUserNotificationCenter
|
|
25
|
+
struct {
|
|
26
|
+
unsigned int willPresentNotification : 1;
|
|
27
|
+
unsigned int didReceiveNotificationResponse : 1;
|
|
28
|
+
unsigned int openSettingsForNotification : 1;
|
|
29
|
+
} originalDelegateRespondsTo;
|
|
30
|
+
|
|
31
|
+
+ (instancetype)sharedInstance {
|
|
32
|
+
static dispatch_once_t once;
|
|
33
|
+
__strong static RNFBMessagingUNUserNotificationCenter *sharedInstance;
|
|
34
|
+
dispatch_once(&once, ^{
|
|
35
|
+
sharedInstance = [[RNFBMessagingUNUserNotificationCenter alloc] init];
|
|
36
|
+
sharedInstance.initialNotification = nil;
|
|
37
|
+
sharedInstance.didOpenSettingsForNotification = NO;
|
|
38
|
+
});
|
|
39
|
+
return sharedInstance;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
- (void)observe {
|
|
43
|
+
static dispatch_once_t once;
|
|
44
|
+
__weak RNFBMessagingUNUserNotificationCenter *weakSelf = self;
|
|
45
|
+
dispatch_once(&once, ^{
|
|
46
|
+
RNFBMessagingUNUserNotificationCenter *strongSelf = weakSelf;
|
|
47
|
+
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
|
48
|
+
if (center.delegate != nil) {
|
|
49
|
+
_originalDelegate = center.delegate;
|
|
50
|
+
originalDelegateRespondsTo.openSettingsForNotification = (unsigned int)[_originalDelegate
|
|
51
|
+
respondsToSelector:@selector(userNotificationCenter:openSettingsForNotification:)];
|
|
52
|
+
originalDelegateRespondsTo.willPresentNotification = (unsigned int)[_originalDelegate
|
|
53
|
+
respondsToSelector:@selector(userNotificationCenter:
|
|
54
|
+
willPresentNotification:withCompletionHandler:)];
|
|
55
|
+
originalDelegateRespondsTo.didReceiveNotificationResponse = (unsigned int)[_originalDelegate
|
|
56
|
+
respondsToSelector:@selector(userNotificationCenter:
|
|
57
|
+
didReceiveNotificationResponse:withCompletionHandler:)];
|
|
58
|
+
}
|
|
59
|
+
center.delegate = strongSelf;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
- (nullable NSDictionary *)getInitialNotification {
|
|
64
|
+
if (_initialNotification != nil) {
|
|
65
|
+
NSDictionary *initialNotificationCopy = [_initialNotification copy];
|
|
66
|
+
_initialNotification = nil;
|
|
67
|
+
return initialNotificationCopy;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return nil;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
- (NSNumber *)getDidOpenSettingsForNotification {
|
|
74
|
+
if (_didOpenSettingsForNotification != NO) {
|
|
75
|
+
_didOpenSettingsForNotification = NO;
|
|
76
|
+
return @YES;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return @NO;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
|
|
83
|
+
willPresentNotification:(UNNotification *)notification
|
|
84
|
+
withCompletionHandler:
|
|
85
|
+
(void (^)(UNNotificationPresentationOptions options))completionHandler {
|
|
86
|
+
NSArray *presentationOptionsConfig =
|
|
87
|
+
[[RNFBJSON shared] getArrayValue:@"messaging_ios_foreground_presentation_options"
|
|
88
|
+
defaultValue:@[]];
|
|
89
|
+
|
|
90
|
+
UNNotificationPresentationOptions presentationOptions = UNNotificationPresentationOptionNone;
|
|
91
|
+
|
|
92
|
+
BOOL badge = [presentationOptionsConfig containsObject:@"badge"];
|
|
93
|
+
BOOL sound = [presentationOptionsConfig containsObject:@"sound"];
|
|
94
|
+
BOOL alert = [presentationOptionsConfig containsObject:@"alert"];
|
|
95
|
+
BOOL list = [presentationOptionsConfig containsObject:@"list"];
|
|
96
|
+
BOOL banner = [presentationOptionsConfig containsObject:@"banner"];
|
|
97
|
+
|
|
98
|
+
if (badge) {
|
|
99
|
+
presentationOptions |= UNNotificationPresentationOptionBadge;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (sound) {
|
|
103
|
+
presentationOptions |= UNNotificationPresentationOptionSound;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// if list or banner is true, ignore `alert` property
|
|
107
|
+
if (banner || list) {
|
|
108
|
+
if (banner) {
|
|
109
|
+
if (@available(iOS 14, *)) {
|
|
110
|
+
presentationOptions |= UNNotificationPresentationOptionBanner;
|
|
111
|
+
} else {
|
|
112
|
+
// for iOS 13 we need to set `alert`
|
|
113
|
+
presentationOptions |= UNNotificationPresentationOptionAlert;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (list) {
|
|
118
|
+
if (@available(iOS 14, *)) {
|
|
119
|
+
presentationOptions |= UNNotificationPresentationOptionList;
|
|
120
|
+
} else {
|
|
121
|
+
// for iOS 13 we need to set `alert`
|
|
122
|
+
presentationOptions |= UNNotificationPresentationOptionAlert;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
} else if (alert) {
|
|
126
|
+
// TODO: Remove `alert` once iOS 14 becomes the minimum deployment target
|
|
127
|
+
presentationOptions |= UNNotificationPresentationOptionAlert;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (notification.request.content.userInfo[@"gcm.message_id"]) {
|
|
131
|
+
NSDictionary *notificationDict = [RNFBMessagingSerializer notificationToDict:notification];
|
|
132
|
+
|
|
133
|
+
// Don't send an event if contentAvailable is true - application:didReceiveRemoteNotification
|
|
134
|
+
// will send the event for us, we don't want to duplicate them
|
|
135
|
+
if (!notificationDict[@"contentAvailable"]) {
|
|
136
|
+
[[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_received"
|
|
137
|
+
body:notificationDict];
|
|
138
|
+
}
|
|
139
|
+
completionHandler(presentationOptions);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (_originalDelegate != nil && originalDelegateRespondsTo.willPresentNotification) {
|
|
143
|
+
[_originalDelegate userNotificationCenter:center
|
|
144
|
+
willPresentNotification:notification
|
|
145
|
+
withCompletionHandler:completionHandler];
|
|
146
|
+
} else {
|
|
147
|
+
completionHandler(presentationOptions);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
|
|
152
|
+
didReceiveNotificationResponse:(UNNotificationResponse *)response
|
|
153
|
+
withCompletionHandler:(void (^)(void))completionHandler {
|
|
154
|
+
NSDictionary *remoteNotification = response.notification.request.content.userInfo;
|
|
155
|
+
if (remoteNotification[@"gcm.message_id"]) {
|
|
156
|
+
NSDictionary *notificationDict =
|
|
157
|
+
[RNFBMessagingSerializer remoteMessageUserInfoToDict:remoteNotification];
|
|
158
|
+
[[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_notification_opened"
|
|
159
|
+
body:notificationDict];
|
|
160
|
+
_initialNotification = notificationDict;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (_originalDelegate != nil && originalDelegateRespondsTo.didReceiveNotificationResponse) {
|
|
164
|
+
[_originalDelegate userNotificationCenter:center
|
|
165
|
+
didReceiveNotificationResponse:response
|
|
166
|
+
withCompletionHandler:completionHandler];
|
|
167
|
+
} else {
|
|
168
|
+
completionHandler();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
|
|
173
|
+
openSettingsForNotification:(nullable UNNotification *)notification {
|
|
174
|
+
if (_originalDelegate != nil && originalDelegateRespondsTo.openSettingsForNotification) {
|
|
175
|
+
[_originalDelegate userNotificationCenter:center openSettingsForNotification:notification];
|
|
176
|
+
} else {
|
|
177
|
+
NSDictionary *notificationDict = [RNFBMessagingSerializer notificationToDict:notification];
|
|
178
|
+
[[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_settings_for_notification_opened"
|
|
179
|
+
body:notificationDict];
|
|
180
|
+
|
|
181
|
+
_didOpenSettingsForNotification = YES;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#import <Foundation/Foundation.h>
|
|
19
|
+
#import <React/RCTBridgeModule.h>
|
|
20
|
+
|
|
21
|
+
@interface RNFBMessagingModule : NSObject <RCTBridgeModule>
|
|
22
|
+
+ (NSDictionary *_Nonnull)addCustomPropsToUserProps:(NSDictionary *_Nullable)userProps
|
|
23
|
+
withLaunchOptions:(NSDictionary *_Nullable)launchOptions;
|
|
24
|
+
@property BOOL isDeliveryMetricsExportToBigQueryEnabled;
|
|
25
|
+
|
|
26
|
+
@end
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#import <Firebase/Firebase.h>
|
|
19
|
+
#import <RNFBApp/RNFBSharedUtils.h>
|
|
20
|
+
#import <React/RCTConvert.h>
|
|
21
|
+
#import <React/RCTUtils.h>
|
|
22
|
+
|
|
23
|
+
#import "RNFBMessaging+AppDelegate.h"
|
|
24
|
+
#import "RNFBMessaging+NSNotificationCenter.h"
|
|
25
|
+
#import "RNFBMessaging+UNUserNotificationCenter.h"
|
|
26
|
+
#import "RNFBMessagingModule.h"
|
|
27
|
+
#import "RNFBMessagingSerializer.h"
|
|
28
|
+
|
|
29
|
+
@implementation RNFBMessagingModule
|
|
30
|
+
#pragma mark -
|
|
31
|
+
#pragma mark Module Setup
|
|
32
|
+
|
|
33
|
+
RCT_EXPORT_MODULE();
|
|
34
|
+
|
|
35
|
+
- (id)init {
|
|
36
|
+
self = [super init];
|
|
37
|
+
return self;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
- (dispatch_queue_t)methodQueue {
|
|
41
|
+
return dispatch_get_main_queue();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
+ (BOOL)requiresMainQueueSetup {
|
|
45
|
+
return YES;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
+ (NSDictionary *)addCustomPropsToUserProps:(NSDictionary *_Nullable)userProps
|
|
49
|
+
withLaunchOptions:(NSDictionary *_Nullable)launchOptions {
|
|
50
|
+
NSMutableDictionary *appProperties =
|
|
51
|
+
userProps != nil ? [userProps mutableCopy] : [NSMutableDictionary dictionary];
|
|
52
|
+
appProperties[@"isHeadless"] = @([RCTConvert BOOL:@(NO)]);
|
|
53
|
+
|
|
54
|
+
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
|
|
55
|
+
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
|
|
56
|
+
appProperties[@"isHeadless"] = @([RCTConvert BOOL:@(YES)]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return [NSDictionary dictionaryWithDictionary:appProperties];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
- (NSDictionary *)constantsToExport {
|
|
64
|
+
NSMutableDictionary *constants = [NSMutableDictionary new];
|
|
65
|
+
constants[@"isAutoInitEnabled"] =
|
|
66
|
+
@([RCTConvert BOOL:@([FIRMessaging messaging].autoInitEnabled)]);
|
|
67
|
+
constants[@"isRegisteredForRemoteNotifications"] = @(
|
|
68
|
+
[RCTConvert BOOL:@([[UIApplication sharedApplication] isRegisteredForRemoteNotifications])]);
|
|
69
|
+
constants[@"isDeliveryMetricsExportToBigQueryEnabled"] =
|
|
70
|
+
@([RCTConvert BOOL:@(_isDeliveryMetricsExportToBigQueryEnabled)]);
|
|
71
|
+
return constants;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#pragma mark -
|
|
75
|
+
#pragma mark Firebase Messaging Methods
|
|
76
|
+
|
|
77
|
+
RCT_EXPORT_METHOD(getInitialNotification
|
|
78
|
+
: (RCTPromiseResolveBlock)resolve
|
|
79
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
80
|
+
resolve([[RNFBMessagingUNUserNotificationCenter sharedInstance] getInitialNotification]);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
RCT_EXPORT_METHOD(getDidOpenSettingsForNotification
|
|
84
|
+
: (RCTPromiseResolveBlock)resolve
|
|
85
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
86
|
+
resolve(
|
|
87
|
+
[[RNFBMessagingUNUserNotificationCenter sharedInstance] getDidOpenSettingsForNotification]);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
RCT_EXPORT_METHOD(setAutoInitEnabled
|
|
91
|
+
: (BOOL)enabled
|
|
92
|
+
: (RCTPromiseResolveBlock)resolve
|
|
93
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
94
|
+
@try {
|
|
95
|
+
[FIRMessaging messaging].autoInitEnabled = enabled;
|
|
96
|
+
} @catch (NSException *exception) {
|
|
97
|
+
return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return resolve([NSNull null]);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
RCT_EXPORT_METHOD(signalBackgroundMessageHandlerSet) {
|
|
104
|
+
DLog(@"signalBackgroundMessageHandlerSet called");
|
|
105
|
+
@try {
|
|
106
|
+
[[RNFBMessagingAppDelegate sharedInstance] signalBackgroundMessageHandlerSet];
|
|
107
|
+
} @catch (NSException *exception) {
|
|
108
|
+
ELog(@"signalBackgroundMessageHandlerSet failed");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
RCT_EXPORT_METHOD(getToken
|
|
113
|
+
: (NSString *)appName
|
|
114
|
+
: (NSString *)senderId
|
|
115
|
+
: (RCTPromiseResolveBlock)resolve
|
|
116
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
117
|
+
if ([UIApplication sharedApplication].isRegisteredForRemoteNotifications == NO) {
|
|
118
|
+
[RNFBSharedUtils
|
|
119
|
+
rejectPromiseWithUserInfo:reject
|
|
120
|
+
userInfo:(NSMutableDictionary *)@{
|
|
121
|
+
@"code" : @"unregistered",
|
|
122
|
+
@"message" :
|
|
123
|
+
@"You must be registered for remote messages before calling "
|
|
124
|
+
@"getToken, see messaging().registerDeviceForRemoteMessages().",
|
|
125
|
+
}];
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// As of firebase-ios-sdk 10.4.0, an APNS token is strictly required for getToken to work
|
|
130
|
+
NSData *apnsToken = [FIRMessaging messaging].APNSToken;
|
|
131
|
+
if (apnsToken == nil) {
|
|
132
|
+
DLog(@"RNFBMessaging getToken - no APNS token is available. Firebase requires an APNS token to "
|
|
133
|
+
@"vend an FCM token in firebase-ios-sdk 10.4.0 and higher. See documentation on "
|
|
134
|
+
@"setAPNSToken and getAPNSToken.")
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
[[FIRMessaging messaging]
|
|
138
|
+
retrieveFCMTokenForSenderID:senderId
|
|
139
|
+
completion:^(NSString *_Nullable token, NSError *_Nullable error) {
|
|
140
|
+
if (error) {
|
|
141
|
+
[RNFBSharedUtils rejectPromiseWithNSError:reject error:error];
|
|
142
|
+
} else {
|
|
143
|
+
resolve(token);
|
|
144
|
+
}
|
|
145
|
+
}];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
RCT_EXPORT_METHOD(deleteToken
|
|
149
|
+
: (NSString *)appName
|
|
150
|
+
: (NSString *)senderId
|
|
151
|
+
: (RCTPromiseResolveBlock)resolve
|
|
152
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
153
|
+
[[FIRMessaging messaging] deleteFCMTokenForSenderID:senderId
|
|
154
|
+
completion:^(NSError *_Nullable error) {
|
|
155
|
+
if (error) {
|
|
156
|
+
[RNFBSharedUtils rejectPromiseWithNSError:reject
|
|
157
|
+
error:error];
|
|
158
|
+
} else {
|
|
159
|
+
resolve([NSNull null]);
|
|
160
|
+
}
|
|
161
|
+
}];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
RCT_EXPORT_METHOD(getAPNSToken : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) {
|
|
165
|
+
NSData *apnsToken = [FIRMessaging messaging].APNSToken;
|
|
166
|
+
if (apnsToken) {
|
|
167
|
+
resolve([RNFBMessagingSerializer APNSTokenFromNSData:apnsToken]);
|
|
168
|
+
} else {
|
|
169
|
+
#if TARGET_IPHONE_SIMULATOR
|
|
170
|
+
#if !TARGET_CPU_ARM64
|
|
171
|
+
DLog(@"RNFBMessaging getAPNSToken - Simulator without APNS support detected, with no token "
|
|
172
|
+
@"set. Use setAPNSToken with an arbitrary string if needed for testing.")
|
|
173
|
+
resolve([NSNull null]);
|
|
174
|
+
return;
|
|
175
|
+
#endif
|
|
176
|
+
DLog(@"RNFBMessaging getAPNSToken - ARM64 Simulator detected, but no APNS token available. "
|
|
177
|
+
@"APNS token may be possible. macOS13+ / iOS16+ / M1 mac required for assumption to be "
|
|
178
|
+
@"valid. "
|
|
179
|
+
@"Use setAPNSToken in testing if needed.");
|
|
180
|
+
#endif
|
|
181
|
+
if ([UIApplication sharedApplication].isRegisteredForRemoteNotifications == NO) {
|
|
182
|
+
[RNFBSharedUtils
|
|
183
|
+
rejectPromiseWithUserInfo:reject
|
|
184
|
+
userInfo:(NSMutableDictionary *)@{
|
|
185
|
+
@"code" : @"unregistered",
|
|
186
|
+
@"message" : @"You must be registered for remote messages before "
|
|
187
|
+
@"calling getAPNSToken, see "
|
|
188
|
+
@"messaging().registerDeviceForRemoteMessages().",
|
|
189
|
+
}];
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
resolve([NSNull null]);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
RCT_EXPORT_METHOD(setAPNSToken
|
|
197
|
+
: (NSString *)token
|
|
198
|
+
: (NSString *)type
|
|
199
|
+
: (RCTPromiseResolveBlock)resolve
|
|
200
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
201
|
+
// Default to unknown (determined by provisioning profile) type, but user may have passed type as
|
|
202
|
+
// param
|
|
203
|
+
FIRMessagingAPNSTokenType tokenType = FIRMessagingAPNSTokenTypeUnknown;
|
|
204
|
+
if (type != nil && [@"prod" isEqualToString:type]) {
|
|
205
|
+
tokenType = FIRMessagingAPNSTokenTypeProd;
|
|
206
|
+
} else if (type != nil && [@"sandbox" isEqualToString:type]) {
|
|
207
|
+
tokenType = FIRMessagingAPNSTokenTypeSandbox;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
[[FIRMessaging messaging] setAPNSToken:[RNFBMessagingSerializer APNSTokenDataFromNSString:token]
|
|
211
|
+
type:tokenType];
|
|
212
|
+
resolve([NSNull null]);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
RCT_EXPORT_METHOD(getIsHeadless : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) {
|
|
216
|
+
RNFBMessagingNSNotificationCenter *notifCenter =
|
|
217
|
+
[RNFBMessagingNSNotificationCenter sharedInstance];
|
|
218
|
+
|
|
219
|
+
return resolve(@([RCTConvert BOOL:@(notifCenter.isHeadless)]));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
RCT_EXPORT_METHOD(completeNotificationProcessing) {
|
|
223
|
+
dispatch_get_main_queue(), ^{
|
|
224
|
+
RNFBMessagingAppDelegate *appDelegate = [RNFBMessagingAppDelegate sharedInstance];
|
|
225
|
+
if (appDelegate.completionHandler) {
|
|
226
|
+
appDelegate.completionHandler(UIBackgroundFetchResultNewData);
|
|
227
|
+
appDelegate.completionHandler = nil;
|
|
228
|
+
}
|
|
229
|
+
if (appDelegate.backgroundTaskId != UIBackgroundTaskInvalid) {
|
|
230
|
+
[[UIApplication sharedApplication] endBackgroundTask:appDelegate.backgroundTaskId];
|
|
231
|
+
appDelegate.backgroundTaskId = UIBackgroundTaskInvalid;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
RCT_EXPORT_METHOD(requestPermission
|
|
237
|
+
: (NSDictionary *)permissions
|
|
238
|
+
: (RCTPromiseResolveBlock)resolve
|
|
239
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
240
|
+
if (RCTRunningInAppExtension()) {
|
|
241
|
+
[RNFBSharedUtils
|
|
242
|
+
rejectPromiseWithUserInfo:reject
|
|
243
|
+
userInfo:[@{
|
|
244
|
+
@"code" : @"unavailable-in-extension",
|
|
245
|
+
@"message" : @"requestPermission can not be called in App Extensions"
|
|
246
|
+
} mutableCopy]];
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
UNAuthorizationOptions options = UNAuthorizationOptionNone;
|
|
251
|
+
|
|
252
|
+
if ([permissions[@"alert"] isEqual:@(YES)]) {
|
|
253
|
+
options |= UNAuthorizationOptionAlert;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if ([permissions[@"badge"] isEqual:@(YES)]) {
|
|
257
|
+
options |= UNAuthorizationOptionBadge;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if ([permissions[@"sound"] isEqual:@(YES)]) {
|
|
261
|
+
options |= UNAuthorizationOptionSound;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if ([permissions[@"criticalAlert"] isEqual:@(YES)]) {
|
|
265
|
+
options |= UNAuthorizationOptionCriticalAlert;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if ([permissions[@"provisional"] isEqual:@(YES)]) {
|
|
269
|
+
options |= UNAuthorizationOptionProvisional;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if ([permissions[@"announcement"] isEqual:@(YES)]) {
|
|
273
|
+
options |= UNAuthorizationOptionAnnouncement;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if ([permissions[@"carPlay"] isEqual:@(YES)]) {
|
|
277
|
+
options |= UNAuthorizationOptionCarPlay;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if ([permissions[@"providesAppNotificationSettings"] isEqual:@(YES)]) {
|
|
281
|
+
options |= UNAuthorizationOptionProvidesAppNotificationSettings;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
|
285
|
+
[center requestAuthorizationWithOptions:options
|
|
286
|
+
completionHandler:^(BOOL granted, NSError *_Nullable error) {
|
|
287
|
+
if (error) {
|
|
288
|
+
[RNFBSharedUtils rejectPromiseWithNSError:reject error:error];
|
|
289
|
+
} else {
|
|
290
|
+
// if we do not attempt to register immediately, registration fails
|
|
291
|
+
// later unknown reason why, but this was the only difference between
|
|
292
|
+
// using a react-native-permissions vs built-in permissions request in
|
|
293
|
+
// a sequence of "request permissions" --> "register for messages" you
|
|
294
|
+
// only want to request permission if you want to register for
|
|
295
|
+
// messages, so we register directly now - see #7272
|
|
296
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
297
|
+
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
|
298
|
+
});
|
|
299
|
+
[self hasPermission:resolve:reject];
|
|
300
|
+
}
|
|
301
|
+
}];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
RCT_EXPORT_METHOD(registerForRemoteNotifications
|
|
305
|
+
: (RCTPromiseResolveBlock)resolve
|
|
306
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
307
|
+
#if TARGET_IPHONE_SIMULATOR
|
|
308
|
+
#if !TARGET_CPU_ARM64
|
|
309
|
+
// Register on this unsupported simulator, but no waiting for a token that won't arrive
|
|
310
|
+
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
|
311
|
+
resolve(@([RCTConvert BOOL:@(YES)]));
|
|
312
|
+
return;
|
|
313
|
+
#endif
|
|
314
|
+
DLog(@"RNFBMessaging registerForRemoteNotifications ARM64 Simulator detected, attempting real "
|
|
315
|
+
@"registration. macOS13+ / iOS16+ / M1 mac required or will timeout.")
|
|
316
|
+
#endif
|
|
317
|
+
if ([UIApplication sharedApplication].isRegisteredForRemoteNotifications == YES) {
|
|
318
|
+
DLog(@"RNFBMessaging registerForRemoteNotifications - already registered.");
|
|
319
|
+
resolve(@([RCTConvert BOOL:@(YES)]));
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
[[RNFBMessagingAppDelegate sharedInstance] setPromiseResolve:resolve andPromiseReject:reject];
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Apple docs recommend that registerForRemoteNotifications is always called on app start
|
|
327
|
+
// regardless of current status
|
|
328
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
329
|
+
// Sometimes the registration never completes, which deserves separate attention in other
|
|
330
|
+
// areas. This area should protect itself against hanging forever regardless. Just in case,
|
|
331
|
+
// check in after a delay and cleanup if required
|
|
332
|
+
dispatch_after(
|
|
333
|
+
dispatch_time(DISPATCH_TIME_NOW, 10.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
|
334
|
+
if ([RNFBMessagingAppDelegate sharedInstance].registerPromiseResolver != nil) {
|
|
335
|
+
// if we got here and resolve/reject are still set, unset, log failure, reject
|
|
336
|
+
DLog(@"RNFBMessaging dispatch_after block: we appear to have timed out. Rejecting");
|
|
337
|
+
[[RNFBMessagingAppDelegate sharedInstance] setPromiseResolve:nil andPromiseReject:nil];
|
|
338
|
+
|
|
339
|
+
[RNFBSharedUtils
|
|
340
|
+
rejectPromiseWithUserInfo:reject
|
|
341
|
+
userInfo:[@{
|
|
342
|
+
@"code" : @"unknown-error",
|
|
343
|
+
@"message" :
|
|
344
|
+
@"registerDeviceForRemoteMessages requested but "
|
|
345
|
+
@"system did not respond. Possibly missing permission."
|
|
346
|
+
} mutableCopy]];
|
|
347
|
+
return;
|
|
348
|
+
} else {
|
|
349
|
+
DLog(@"RNFBMessaging dispatch_after: registerDeviceForRemoteMessages handled.");
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
RCT_EXPORT_METHOD(unregisterForRemoteNotifications
|
|
359
|
+
: (RCTPromiseResolveBlock)resolve
|
|
360
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
361
|
+
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
|
|
362
|
+
resolve(nil);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
RCT_EXPORT_METHOD(hasPermission : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) {
|
|
366
|
+
[[UNUserNotificationCenter currentNotificationCenter]
|
|
367
|
+
getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *_Nonnull settings) {
|
|
368
|
+
NSNumber *authorizedStatus = @-1;
|
|
369
|
+
if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
|
|
370
|
+
authorizedStatus = @-1;
|
|
371
|
+
} else if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
|
|
372
|
+
authorizedStatus = @0;
|
|
373
|
+
} else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
|
|
374
|
+
authorizedStatus = @1;
|
|
375
|
+
} else if (settings.authorizationStatus == UNAuthorizationStatusProvisional) {
|
|
376
|
+
authorizedStatus = @2;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (@available(iOS 14.0, macCatalyst 14.0, *)) {
|
|
380
|
+
if (settings.authorizationStatus == UNAuthorizationStatusEphemeral) {
|
|
381
|
+
authorizedStatus = @3;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
resolve(authorizedStatus);
|
|
386
|
+
}];
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
RCT_EXPORT_METHOD(subscribeToTopic
|
|
390
|
+
: (NSString *)topic
|
|
391
|
+
: (RCTPromiseResolveBlock)resolve
|
|
392
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
393
|
+
[[FIRMessaging messaging] subscribeToTopic:topic
|
|
394
|
+
completion:^(NSError *error) {
|
|
395
|
+
if (error) {
|
|
396
|
+
[RNFBSharedUtils rejectPromiseWithNSError:reject error:error];
|
|
397
|
+
} else {
|
|
398
|
+
resolve(nil);
|
|
399
|
+
}
|
|
400
|
+
}];
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
RCT_EXPORT_METHOD(unsubscribeFromTopic
|
|
404
|
+
: (NSString *)topic
|
|
405
|
+
: (RCTPromiseResolveBlock)resolve
|
|
406
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
407
|
+
[[FIRMessaging messaging] unsubscribeFromTopic:topic
|
|
408
|
+
completion:^(NSError *error) {
|
|
409
|
+
if (error) {
|
|
410
|
+
[RNFBSharedUtils rejectPromiseWithNSError:reject
|
|
411
|
+
error:error];
|
|
412
|
+
} else {
|
|
413
|
+
resolve(nil);
|
|
414
|
+
}
|
|
415
|
+
}];
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
RCT_EXPORT_METHOD(setDeliveryMetricsExportToBigQuery
|
|
419
|
+
: (BOOL)enabled
|
|
420
|
+
: (RCTPromiseResolveBlock)resolve
|
|
421
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
422
|
+
@try {
|
|
423
|
+
_isDeliveryMetricsExportToBigQueryEnabled = enabled;
|
|
424
|
+
} @catch (NSException *exception) {
|
|
425
|
+
return [RNFBSharedUtils rejectPromiseWithExceptionDict:reject exception:exception];
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return resolve([NSNull null]);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
@end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#import <Firebase/Firebase.h>
|
|
19
|
+
#import <Foundation/Foundation.h>
|
|
20
|
+
#import <React/RCTBridgeModule.h>
|
|
21
|
+
|
|
22
|
+
@interface RNFBMessagingSerializer : NSObject
|
|
23
|
+
|
|
24
|
+
+ (NSData *)APNSTokenDataFromNSString:(NSString *)token;
|
|
25
|
+
|
|
26
|
+
+ (NSString *)APNSTokenFromNSData:(NSData *)tokenData;
|
|
27
|
+
|
|
28
|
+
+ (NSDictionary *)notificationToDict:(UNNotification *)notification;
|
|
29
|
+
|
|
30
|
+
+ (NSDictionary *)remoteMessageUserInfoToDict:(NSDictionary *)userInfo;
|
|
31
|
+
|
|
32
|
+
@end
|