[ios][notifications] Handle messaging token refreshed before bridge initialised #960
This commit is contained in:
parent
93b4e3e052
commit
3a5686c226
|
@ -18,6 +18,8 @@
|
||||||
@implementation RNFirebaseMessaging
|
@implementation RNFirebaseMessaging
|
||||||
|
|
||||||
static RNFirebaseMessaging *theRNFirebaseMessaging = nil;
|
static RNFirebaseMessaging *theRNFirebaseMessaging = nil;
|
||||||
|
static bool jsReady = FALSE;
|
||||||
|
static NSString* initialToken = nil;
|
||||||
|
|
||||||
+ (nonnull instancetype)instance {
|
+ (nonnull instancetype)instance {
|
||||||
return theRNFirebaseMessaging;
|
return theRNFirebaseMessaging;
|
||||||
|
@ -66,7 +68,7 @@ RCT_EXPORT_MODULE()
|
||||||
// Listen for FCM data messages that arrive as a remote notification
|
// Listen for FCM data messages that arrive as a remote notification
|
||||||
- (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo {
|
- (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo {
|
||||||
NSDictionary *message = [self parseUserInfo:userInfo];
|
NSDictionary *message = [self parseUserInfo:userInfo];
|
||||||
[RNFirebaseUtil sendJSEvent:self name:MESSAGING_MESSAGE_RECEIVED body:message];
|
[self sendJSEvent:self name:MESSAGING_MESSAGE_RECEIVED body:message];
|
||||||
}
|
}
|
||||||
|
|
||||||
// *******************************************************
|
// *******************************************************
|
||||||
|
@ -82,13 +84,13 @@ RCT_EXPORT_MODULE()
|
||||||
// Listen for FCM tokens
|
// Listen for FCM tokens
|
||||||
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
|
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
|
||||||
NSLog(@"Received new FCM token: %@", fcmToken);
|
NSLog(@"Received new FCM token: %@", fcmToken);
|
||||||
[RNFirebaseUtil sendJSEvent:self name:MESSAGING_TOKEN_REFRESHED body:fcmToken];
|
[self sendJSEvent:self name:MESSAGING_TOKEN_REFRESHED body:fcmToken];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for data messages in the foreground
|
// Listen for data messages in the foreground
|
||||||
- (void)applicationReceivedRemoteMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage {
|
- (void)applicationReceivedRemoteMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage {
|
||||||
NSDictionary *message = [self parseFIRMessagingRemoteMessage:remoteMessage];
|
NSDictionary *message = [self parseFIRMessagingRemoteMessage:remoteMessage];
|
||||||
[RNFirebaseUtil sendJSEvent:self name:MESSAGING_MESSAGE_RECEIVED body:message];
|
[self sendJSEvent:self name:MESSAGING_MESSAGE_RECEIVED body:message];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
|
// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
|
||||||
|
@ -96,7 +98,7 @@ RCT_EXPORT_MODULE()
|
||||||
- (void)messaging:(nonnull FIRMessaging *)messaging
|
- (void)messaging:(nonnull FIRMessaging *)messaging
|
||||||
didReceiveMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage {
|
didReceiveMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage {
|
||||||
NSDictionary *message = [self parseFIRMessagingRemoteMessage:remoteMessage];
|
NSDictionary *message = [self parseFIRMessagingRemoteMessage:remoteMessage];
|
||||||
[RNFirebaseUtil sendJSEvent:self name:MESSAGING_MESSAGE_RECEIVED body:message];
|
[self sendJSEvent:self name:MESSAGING_MESSAGE_RECEIVED body:message];
|
||||||
}
|
}
|
||||||
|
|
||||||
// *******************************************************
|
// *******************************************************
|
||||||
|
@ -120,11 +122,11 @@ RCT_EXPORT_METHOD(requestPermission:(RCTPromiseResolveBlock)resolve rejecter:(RC
|
||||||
[RCTSharedApplication() registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:types categories:nil]];
|
[RCTSharedApplication() registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:types categories:nil]];
|
||||||
// We set the promise for usage by the AppDelegate callback which listens
|
// We set the promise for usage by the AppDelegate callback which listens
|
||||||
// for the result of the permission request
|
// for the result of the permission request
|
||||||
_permissionRejecter = reject;
|
self.permissionRejecter = reject;
|
||||||
_permissionResolver = resolve;
|
self.permissionResolver = resolve;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
if (@available(iOS 10.0, *)) {
|
||||||
// For iOS 10 display notification (sent via APNS)
|
// For iOS 10 display notification (sent via APNS)
|
||||||
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
|
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
|
||||||
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
||||||
|
@ -134,7 +136,7 @@ RCT_EXPORT_METHOD(requestPermission:(RCTPromiseResolveBlock)resolve rejecter:(RC
|
||||||
reject(@"messaging/permission_error", @"Failed to grant permission", error);
|
reject(@"messaging/permission_error", @"Failed to grant permission", error);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
@ -149,11 +151,11 @@ RCT_EXPORT_METHOD(hasPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPro
|
||||||
resolve(@([RCTSharedApplication() currentUserNotificationSettings].types != UIUserNotificationTypeNone));
|
resolve(@([RCTSharedApplication() currentUserNotificationSettings].types != UIUserNotificationTypeNone));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
if (@available(iOS 10.0, *)) {
|
||||||
[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
|
[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
|
||||||
resolve(@(settings.alertSetting == UNNotificationSettingEnabled));
|
resolve(@(settings.alertSetting == UNNotificationSettingEnabled));
|
||||||
}];
|
}];
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +191,31 @@ RCT_EXPORT_METHOD(unsubscribeFromTopic: (NSString*) topic
|
||||||
resolve(nil);
|
resolve(nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(jsInitialised:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||||
|
jsReady = TRUE;
|
||||||
|
resolve(nil);
|
||||||
|
if (initialToken) {
|
||||||
|
[self sendJSEvent:self name:MESSAGING_TOKEN_REFRESHED body:initialToken];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ** Start internals **
|
// ** Start internals **
|
||||||
|
|
||||||
|
// Because of the time delay between the app starting and the bridge being initialised
|
||||||
|
// we catch any events that are received before the JS is ready to receive them
|
||||||
|
- (void)sendJSEvent:(RCTEventEmitter *)emitter name:(NSString *)name body:(id)body {
|
||||||
|
if (emitter.bridge && jsReady) {
|
||||||
|
[RNFirebaseUtil sendJSEvent:emitter name:name body:body];
|
||||||
|
} else {
|
||||||
|
if ([name isEqualToString:MESSAGING_TOKEN_REFRESHED]) {
|
||||||
|
initialToken = body;
|
||||||
|
} else {
|
||||||
|
// TODO: Is this even possible?
|
||||||
|
NSLog(@"Received Remote Message before the bridge is ready");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (NSDictionary*)parseFIRMessagingRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage {
|
- (NSDictionary*)parseFIRMessagingRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage {
|
||||||
NSDictionary *appData = remoteMessage.appData;
|
NSDictionary *appData = remoteMessage.appData;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* @flow
|
* @flow
|
||||||
* Messaging (FCM) representation wrapper
|
* Messaging (FCM) representation wrapper
|
||||||
*/
|
*/
|
||||||
|
import { Platform } from 'react-native';
|
||||||
import { SharedEventEmitter } from '../../utils/events';
|
import { SharedEventEmitter } from '../../utils/events';
|
||||||
import INTERNALS from '../../utils/internals';
|
import INTERNALS from '../../utils/internals';
|
||||||
import { getLogger } from '../../utils/log';
|
import { getLogger } from '../../utils/log';
|
||||||
|
@ -63,6 +64,11 @@ export default class Messaging extends ModuleBase {
|
||||||
SharedEventEmitter.emit('onTokenRefresh', token);
|
SharedEventEmitter.emit('onTokenRefresh', token);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Tell the native module that we're ready to receive events
|
||||||
|
if (Platform.OS === 'ios') {
|
||||||
|
getNativeModule(this).jsInitialised();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getToken(): Promise<string> {
|
getToken(): Promise<string> {
|
||||||
|
|
Loading…
Reference in New Issue