Commit 2265afa9 authored by Libin Lu's avatar Libin Lu Committed by GitHub

hold notification when app is bootstrapping

parent 51ea457d
...@@ -140,7 +140,7 @@ typedef NS_ENUM(NSUInteger, UNNotificationActionType) { ...@@ -140,7 +140,7 @@ typedef NS_ENUM(NSUInteger, UNNotificationActionType) {
+ (UNNotificationAction *) UNNotificationAction:(id)json { + (UNNotificationAction *) UNNotificationAction:(id)json {
NSDictionary<NSString *, id> *details = [self NSDictionary:json]; NSDictionary<NSString *, id> *details = [self NSDictionary:json];
NSString *identifier = [RCTConvert NSString: details[@"id"]]; NSString *identifier = [RCTConvert NSString: details[@"id"]];
NSString *title = [RCTConvert NSString: details[@"title"]]; NSString *title = [RCTConvert NSString: details[@"title"]];
UNNotificationActionOptions options = [RCTConvert UNNotificationActionOptions: details[@"options"]]; UNNotificationActionOptions options = [RCTConvert UNNotificationActionOptions: details[@"options"]];
...@@ -152,11 +152,11 @@ typedef NS_ENUM(NSUInteger, UNNotificationActionType) { ...@@ -152,11 +152,11 @@ typedef NS_ENUM(NSUInteger, UNNotificationActionType) {
return [UNTextInputNotificationAction actionWithIdentifier:identifier title:title options:options textInputButtonTitle:textInputButtonTitle textInputPlaceholder:textInputPlaceholder]; return [UNTextInputNotificationAction actionWithIdentifier:identifier title:title options:options textInputButtonTitle:textInputButtonTitle textInputPlaceholder:textInputPlaceholder];
} }
return [UNNotificationAction actionWithIdentifier:identifier return [UNNotificationAction actionWithIdentifier:identifier
title:title title:title
options:options]; options:options];
} }
RCT_ENUM_CONVERTER(UNNotificationActionType, (@{ RCT_ENUM_CONVERTER(UNNotificationActionType, (@{
...@@ -180,9 +180,9 @@ RCT_MULTI_ENUM_CONVERTER(UNNotificationActionOptions, (@{ ...@@ -180,9 +180,9 @@ RCT_MULTI_ENUM_CONVERTER(UNNotificationActionOptions, (@{
+ (UNNotificationCategory *) UNNotificationCategory:(id)json { + (UNNotificationCategory *) UNNotificationCategory:(id)json {
NSDictionary<NSString *, id> *details = [self NSDictionary:json]; NSDictionary<NSString *, id> *details = [self NSDictionary:json];
NSString *identifier = [RCTConvert NSString: details[@"id"]]; NSString *identifier = [RCTConvert NSString: details[@"id"]];
NSMutableArray *actions = [[NSMutableArray alloc] init]; NSMutableArray *actions = [[NSMutableArray alloc] init];
for (NSDictionary *actionDict in details[@"actions"]) { for (NSDictionary *actionDict in details[@"actions"]) {
[actions addObject:[RCTConvert UNNotificationAction:actionDict]]; [actions addObject:[RCTConvert UNNotificationAction:actionDict]];
...@@ -194,7 +194,7 @@ RCT_MULTI_ENUM_CONVERTER(UNNotificationActionOptions, (@{ ...@@ -194,7 +194,7 @@ RCT_MULTI_ENUM_CONVERTER(UNNotificationActionOptions, (@{
if (hiddenPreviewsBodyPlaceholder) { if (hiddenPreviewsBodyPlaceholder) {
#if defined(__IPHONE_11_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 #if defined(__IPHONE_11_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
return [UNNotificationCategory categoryWithIdentifier:identifier actions:actions intentIdentifiers:intentIdentifiers hiddenPreviewsBodyPlaceholder:hiddenPreviewsBodyPlaceholder options:options]; return [UNNotificationCategory categoryWithIdentifier:identifier actions:actions intentIdentifiers:intentIdentifiers hiddenPreviewsBodyPlaceholder:hiddenPreviewsBodyPlaceholder options:options];
#endif #endif
} }
...@@ -217,14 +217,15 @@ RCT_MULTI_ENUM_CONVERTER(UNNotificationCategoryOptions, (@{ ...@@ -217,14 +217,15 @@ RCT_MULTI_ENUM_CONVERTER(UNNotificationCategoryOptions, (@{
@end @end
static NSDictionary *initialNotificationActionResponse;
@interface RNFIRMessaging () @interface RNFIRMessaging ()
@property (nonatomic, strong) NSMutableDictionary *notificationCallbacks; @property (nonatomic, strong) NSMutableDictionary *notificationCallbacks;
@end @end
@implementation RNFIRMessaging @implementation RNFIRMessaging
static bool jsHandlerRegistered;
static NSMutableArray* pendingNotifications;
RCT_EXPORT_MODULE(); RCT_EXPORT_MODULE();
- (NSArray<NSString *> *)supportedEvents { - (NSArray<NSString *> *)supportedEvents {
...@@ -239,14 +240,14 @@ RCT_EXPORT_MODULE(); ...@@ -239,14 +240,14 @@ RCT_EXPORT_MODULE();
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: userInfo]; NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: userInfo];
[data setValue:@"remote_notification" forKey:@"_notificationType"]; [data setValue:@"remote_notification" forKey:@"_notificationType"];
[data setValue:@(RCTSharedApplication().applicationState == UIApplicationStateInactive) forKey:@"opened_from_tray"]; [data setValue:@(RCTSharedApplication().applicationState == UIApplicationStateInactive) forKey:@"opened_from_tray"];
[[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:@{@"data": data, @"completionHandler": completionHandler}]; [self sendNotificationEventWhenAvailable:@{@"data": data, @"completionHandler": completionHandler}];
} }
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification { + (void)didReceiveLocalNotification:(UILocalNotification *)notification {
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: notification.userInfo]; NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: notification.userInfo];
[data setValue:@"local_notification" forKey:@"_notificationType"]; [data setValue:@"local_notification" forKey:@"_notificationType"];
[data setValue:@(RCTSharedApplication().applicationState == UIApplicationStateInactive) forKey:@"opened_from_tray"]; [data setValue:@(RCTSharedApplication().applicationState == UIApplicationStateInactive) forKey:@"opened_from_tray"];
[[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:@{@"data": data}]; [self sendNotificationEventWhenAvailable:@{@"data": data}];
} }
+ (void)didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(nonnull RCTNotificationResponseCallback)completionHandler + (void)didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(nonnull RCTNotificationResponseCallback)completionHandler
...@@ -261,24 +262,30 @@ RCT_EXPORT_MODULE(); ...@@ -261,24 +262,30 @@ RCT_EXPORT_MODULE();
if ([response isKindOfClass:UNTextInputNotificationResponse.class]) { if ([response isKindOfClass:UNTextInputNotificationResponse.class]) {
[data setValue:[(UNTextInputNotificationResponse *)response userText] forKey:@"_userText"]; [data setValue:[(UNTextInputNotificationResponse *)response userText] forKey:@"_userText"];
} }
NSDictionary *userInfo = @{@"data": data, @"completionHandler": completionHandler}; NSDictionary *userInfo = @{@"data": data, @"completionHandler": completionHandler};
[self sendNotificationEventWhenAvailable:userInfo];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (data[@"_actionIdentifier"] && ![data[@"_actionIdentifier"] isEqualToString:UNNotificationDefaultActionIdentifier]) {
initialNotificationActionResponse = userInfo;
}
});
[[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:userInfo];
} }
+ (void)willPresentNotification:(UNNotification *)notification withCompletionHandler:(nonnull RCTWillPresentNotificationCallback)completionHandler + (void)willPresentNotification:(UNNotification *)notification withCompletionHandler:(nonnull RCTWillPresentNotificationCallback)completionHandler
{ {
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: notification.request.content.userInfo]; NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: notification.request.content.userInfo];
[data setValue:@"will_present_notification" forKey:@"_notificationType"]; [data setValue:@"will_present_notification" forKey:@"_notificationType"];
[[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:@{@"data": data, @"completionHandler": completionHandler}]; [self sendNotificationEventWhenAvailable:@{@"data": data, @"completionHandler": completionHandler}];
}
+ (void)sendNotificationEventWhenAvailable:(NSDictionary*)data
{
if(!jsHandlerRegistered){
// JS hasn't registered callback yet. hold on that
if(!pendingNotifications){
pendingNotifications = [NSMutableArray array];
}
[pendingNotifications addObject:data];
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:data];
}
} }
- (void)dealloc - (void)dealloc
...@@ -288,10 +295,11 @@ RCT_EXPORT_MODULE(); ...@@ -288,10 +295,11 @@ RCT_EXPORT_MODULE();
- (instancetype)init { - (instancetype)init {
self = [super init]; self = [super init];
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleNotificationReceived:) selector:@selector(handleNotificationReceived:)
name:FCMNotificationReceived name:FCMNotificationReceived
object:nil]; object:nil];
[[NSNotificationCenter defaultCenter] [[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(sendDataMessageFailure:) addObserver:self selector:@selector(sendDataMessageFailure:)
...@@ -309,17 +317,26 @@ RCT_EXPORT_MODULE(); ...@@ -309,17 +317,26 @@ RCT_EXPORT_MODULE();
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[[FIRMessaging messaging] setDelegate:self]; [[FIRMessaging messaging] setDelegate:self];
}); });
return self; return self;
} }
-(void) addListener:(NSString *)eventName { -(void) addListener:(NSString *)eventName {
if([super respondsToSelector:@selector(addListener:)]){ [super addListener:eventName];
[super addListener:eventName];
}
if([eventName isEqualToString:FCMNotificationReceived] && initialNotificationActionResponse) { if([eventName isEqualToString:FCMNotificationReceived]) {
[[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:[initialNotificationActionResponse copy]]; static dispatch_once_t onceToken;
} dispatch_once(&onceToken, ^{
jsHandlerRegistered = true;
for (NSDictionary* data in pendingNotifications) {
[[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:data];
}
[pendingNotifications removeAllObjects];
});
}
} }
RCT_EXPORT_METHOD(enableDirectChannel) RCT_EXPORT_METHOD(enableDirectChannel)
...@@ -336,6 +353,7 @@ RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecte ...@@ -336,6 +353,7 @@ RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecte
{ {
NSDictionary* initialNotif; NSDictionary* initialNotif;
NSDictionary *localUserInfo = [[self.bridge.launchOptions[UIApplicationLaunchOptionsLocalNotificationKey] userInfo] mutableCopy]; NSDictionary *localUserInfo = [[self.bridge.launchOptions[UIApplicationLaunchOptionsLocalNotificationKey] userInfo] mutableCopy];
NSDictionary *remoteUserInfo = [self.bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] mutableCopy]; NSDictionary *remoteUserInfo = [self.bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] mutableCopy];
if(localUserInfo){ if(localUserInfo){
initialNotif = localUserInfo; initialNotif = localUserInfo;
...@@ -346,10 +364,13 @@ RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecte ...@@ -346,10 +364,13 @@ RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecte
[initialNotif setValue:@YES forKey:@"opened_from_tray"]; [initialNotif setValue:@YES forKey:@"opened_from_tray"];
resolve(initialNotif); resolve(initialNotif);
} else { } else {
resolve(nil);
resolve([self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityTypeKey] copy]);
} }
} }
RCT_EXPORT_METHOD(getAPNSToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) RCT_EXPORT_METHOD(getAPNSToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSData * deviceToken = [FIRMessaging messaging].APNSToken; NSData * deviceToken = [FIRMessaging messaging].APNSToken;
...@@ -366,47 +387,16 @@ RCT_EXPORT_METHOD(getFCMToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromi ...@@ -366,47 +387,16 @@ RCT_EXPORT_METHOD(getFCMToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromi
resolve([FIRMessaging messaging].FCMToken); resolve([FIRMessaging messaging].FCMToken);
} }
RCT_EXPORT_METHOD(getEntityFCMToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
FIROptions *options = FIROptions.defaultOptions;
NSString *entity = options.GCMSenderID;
NSData * deviceToken = [FIRMessaging messaging].APNSToken;
[[FIRInstanceID instanceID]tokenWithAuthorizedEntity:entity scope:kFIRInstanceIDScopeFirebaseMessaging options:@{@"apns_token": deviceToken} handler:^(NSString * _Nullable token, NSError * _Nullable error) {
if (error != nil) {
reject([NSString stringWithFormat:@"%ld",error.code],error.localizedDescription,nil);
} else {
resolve(token);
}
}];
}
RCT_EXPORT_METHOD(deleteEntityFCMToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
FIROptions *options = FIROptions.defaultOptions;;
NSString *entity = options.GCMSenderID;
[[FIRInstanceID instanceID]deleteTokenWithAuthorizedEntity:entity scope:kFIRInstanceIDScopeFirebaseMessaging handler:^(NSError * _Nullable error) {
if (error != nil) {
reject([NSString stringWithFormat:@"%ld",error.code],error.localizedDescription,nil);
} else {
resolve(nil);
}
}];
}
RCT_EXPORT_METHOD(deleteInstanceId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) RCT_EXPORT_METHOD(deleteInstanceId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{ {
[[FIRInstanceID instanceID]deleteIDWithHandler:^(NSError * _Nullable error) { [[FIRInstanceID instanceID]deleteIDWithHandler:^(NSError * _Nullable error) {
if (error != nil) { if (error != nil) {
reject([NSString stringWithFormat:@"%ld",error.code],error.localizedDescription,nil); reject([NSString stringWithFormat:@"%ld",error.code],error.localizedDescription,nil);
} else { } else {
resolve(nil); resolve(nil);
} }
}]; }];
} }
- (void)messaging:(nonnull FIRMessaging *)messaging didRefreshRegistrationToken:(nonnull NSString *)fcmToken { - (void)messaging:(nonnull FIRMessaging *)messaging didRefreshRegistrationToken:(nonnull NSString *)fcmToken {
...@@ -655,12 +645,7 @@ RCT_EXPORT_METHOD(finishNotificationResponse: (NSString *)completionHandlerId){ ...@@ -655,12 +645,7 @@ RCT_EXPORT_METHOD(finishNotificationResponse: (NSString *)completionHandlerId){
self.notificationCallbacks[completionHandlerId] = completionHandler; self.notificationCallbacks[completionHandlerId] = completionHandler;
data[@"_completionHandlerId"] = completionHandlerId; data[@"_completionHandlerId"] = completionHandlerId;
} }
[self sendEventWithName:FCMNotificationReceived body:data]; [self sendEventWithName:FCMNotificationReceived body:data];
if (initialNotificationActionResponse) {
initialNotificationActionResponse = nil;
}
} }
- (void)sendDataMessageFailure:(NSNotification *)notification - (void)sendDataMessageFailure:(NSNotification *)notification
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment