Open jhondavila opened 4 years ago
what is the update ?? did you solve it ?? Foreground is fix ?
same issue
I have working solution, I'll post it later today.
Please note that UNUserNotificationCenter
is available in iOS 10+, so if your app needs to support iOS 9, you'll need to wrap appropriate parts of code in conditional blocks.
More about UNUserNotificationCenter
in the documentation: https://developer.apple.com/documentation/usernotifications/unusernotificationcenter?language=objc
AppDelegate.h
#import <UserNotifications/UserNotifications.h>
UNUserNotificationCenterDelegate
in @implements
block@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate> // Add UNUserNotificationCenterDelegate to the list, in my case it looks like this
AppDelegate.m
Add new import to the imports section in the top of the file
#import <UserNotifications/UserNotifications.h>
Add following code to the bottom of didFinishLaunchingWithOptions
method (before return):
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
willPresentNotification
method. Code below will present all notifications in the foreground.// Manage notifications while app is in the foreground
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
In the willPresentNotification
method you can control which notifications to show. I.e. in our app we only present one type of notifications in the foreground. The type of notification is added to apns payload.
Example:
// Manage notifications while app is in the foreground
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
NSDictionary *userInfo = notification.request.content.userInfo; // read apns payload
NSString *notificationType = userInfo[@"notificationType"]; // check your notification type
if (![notificationType isEqual: @"some custom type"]) { // we silence all notifications which do not match our custom notification type
completionHandler(UNNotificationPresentationOptionNone);
return;
}
// custom notification type is displayed normally
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
Hope this helps
Can we close this issue now or maybe we should add info above to the docs for people with the same issue?
this solved my problem
I got an error at: (void)didReceiveRemoteNotification:(NSDictionary *)notification
Error message: There is no completion handler with notification id: xxx-xxx-xxx
// Called when a user taps on a notification in the foreground
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler
{
NSMutableDictionary *userData = [NSMutableDictionary dictionaryWithDictionary:response.notification.request.content.userInfo];
[userData setObject:@YES forKey:@"userInteraction"];
[RNCPushNotificationIOS didReceiveRemoteNotification:userData]; <<---- this
}
Is there any way to conditionally hide remote notifications in the foreground (for instance if you are already looking at the chat thread that the message applies to)? I find that if I add willPresentNotification, notifications are shown in the foreground always and onNotification is only fired when the user clicks it. If I remove it, notifications are hidden in the foreground, but onNotification fires right away. I tried to send a local notification in this scenario, but of course it is not shown in the foreground either.
@brianomchugh
Is there any way to conditionally hide remote notifications in the foreground (for instance if you are already looking at the chat thread that the message applies to)
If you would read carefully my message (https://github.com/react-native-community/react-native-push-notification-ios/issues/63#issuecomment-583618575) you would find the example at the very bottom.
Just pass UNNotificationPresentationOptionNone
to completionHandler
if you would like to not present particular notification.
@dominiczaq
Yes I saw that example-- your condition is some value in the notification payload. I am more talking about some condition in the javascript code. For instance, in the iOS Messages app, a notification is shown when the app is in the foreground and you are viewing a different conversation, but not if you are already viewing that conversation or the conversation list. Im trying to figure out how to replicate that but it doesn't seem possible without a native solution.
It's quite possible. When you want to block notification you need to save that information in the variable in the native side. When notification is received just read that variable and decide based on that.
OK this is what I came up with based off of your help @dominiczaq . I don't know much on the native side, so this is hacky-- but it might help others looking to selectively block push notifications in the foreground:
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
NSDictionary *userInfo = notification.request.content.userInfo; // read apns payload
NSString *newConversationKey = [userInfo objectForKey:@"from_msg"];
//read stored focusedConversationKey from user defaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *previousConversationKey = [defaults objectForKey:@"focusedConversationKey"];
//if notification applies to conversation that is already in focus
if([newConversationKey isEqualToString:previousConversationKey]) {
NSLog(@"Already focused on conversation. Hiding Push Notification");
//add "conversationAlreadyFocused" value to notification, so this case can be tested for in the javascript onNotification handler
NSMutableDictionary *userInfoMutable = [userInfo mutableCopy];
userInfoMutable[@"conversationAlreadyFocused"] = @"true";
userInfo = [NSDictionary dictionaryWithDictionary:userInfoMutable];
//Still call the javascript onNotification handler so it can display the new message right away
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo];
//hide push notification
completionHandler(UNNotificationPresentationOptionNone);
} else {
NSLog(@"New notification does not apply to currently focused conversation. Showing Push Notification.");
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
return;
}
I still can't get foreground notifications to work:
When API sends a notificationRequest APN it does trigger a notification and localNotification also gets shown but only when app is in the background. I would like to show all notifications when app is foregrounded.
"react-native": "^0.61.5"
"@react-native-community/push-notification-ios": "^1.1.1"
AppDelegate.h
:
...
#import <UserNotifications/UNUserNotificationCenter.h>
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
...
AppDelegate.m
:
#import <RNCPushNotificationIOS.h>
#import <UserNotifications/UserNotifications.h>
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
return YES;
}
// Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
@end
If you are using firebase and it is not working, you might wanna look at invertase/react-native-firebase#3367
I still can't get foreground notifications to work:
@kyytiPetteri I followed every instruction to the T several times over, and still couldn't get it to work. After a day and a half of messing around, I right-clicked userNotificationCenter
to jump to its definition so I could have a look. Much to my surprise, it presented two definitions. One of which was RNFB.
🎉 Instant clarity! I've upgraded from RN 0.59 to 0.61.5 months ago, and then to 0.62.2 recently. React Native Firebase (which I only use for Android...) had auto-linked into my iOS build.
I skipped auto-linking for the related packages, nuked and reinstalled my pods, and my foreground notifications now work as intended again.
For those of you upgrading from version 1.1.1 to 1.2.0 please be aware that there was some breaking changes introduced (and not yet documented with how foreground notifications are handled. Specifically, before 1.2.0, native notifications would not be handled if app was in foreground and now they are. If you'd like to keep legacy behavior, I recommend changing your willPresentNotification as follows:
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
//Still call the javascript onNotification handler so it can display the new message right away
NSDictionary *userInfo = notification.request.content.userInfo;
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo];
//hide push notification
completionHandler(UNNotificationPresentationOptionNone);
}
Hi, prior to implementing the additions in this page, I could not get onNotification
to trigger. After keithhackbarth
comment, I got the onNotification
to trigger, but I also get the error There is no completion handler with notification id
. I am not using react-native-firebase
. I don't know what this error means.
It seems like if I comment out notification.finish(PushNotificationIOS.FetchResult.NoData)
, I do not get that issue. However, it shows as required in the documentation of react-native-push-notification
which I use: https://github.com/zo0r/react-native-push-notification#usage
I thought I got it to work with @keithhackbarth code but now I have the same issue as @kovkev. "There is no completion handler with notification id" I just want to have the following behavior:
onNotification
when the user tap on it. (OK)onNotification
in order to silently update the app data.(KO)I agree, it's working without the notification.finish
line. I used:
onNotification: function (notification) {
console.log(notification);
if (!notification.foreground) {
notification.finish(PushNotificationIOS.FetchResult.NoData);
}
},
But I don't know if this can cause any issue
I've also updated this library and followed the same steps of migration/installation. Now, getting push notifications when app is inactive or in background but not when app is in foreground. I think 'willPresentNotification' is not getting triggered, tried to do some NSLogs in that method but couldn't find anything on console.
I have also tried all of these workarounds in this thread and several others and I am still not seeing onNotification triggered while the app is in the foreground/background. It is only triggered when the app is completely killed and a notification is selected.
I set it up with the last version and this part work for me, when the app is in background/foreground and I click the notification, onNotification is triggered !
@Thomas-Negrault what do you mean the last version? Are you meaning the suggestion from @keithhackbarth and also removing the notification.finish line? Or are you talking about an actual specific version of push-notification-ios or react-native-push-notification?
It seems some people in this thread have the issue after updating from an old version of this library to the last one, and that’s what causing the issue. In my case it’s a recent install from scratch. Maybe some change require by an old version of this library is now causing issues.
@keithhackbarth's fix with a small change worked for me. I just gave it an empty completion handler to avoid the "There is no completion handler with notification id" error:
// Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
// Still call the JS onNotification handler so it can display the new message right away
NSDictionary *userInfo = notification.request.content.userInfo;
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo
fetchCompletionHandler:^void (UIBackgroundFetchResult result){}];
// hide push notification
completionHandler(UNNotificationPresentationOptionNone);
}
Thanks a lot @lowell-list-cambia it's working fine with your code !
I hope the willPresentNotification
will call a js function to check if we display it or not.
I tried all of the solutions but i can't show the notifications in the foreground . My full code is `/**
// Implement UNUserNotificationCenterDelegate to receive display notification via APNS for devices
// running iOS 10 and above.
@interface AppDelegate ()
@implementation AppDelegate
NSString *const kGCMMessageIDKey = @"gcm.message_id";
(BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions { // Use Firebase library to configure APIs // [START configure_firebase] if ([FIRApp defaultApp] == nil) { [FIRApp configure]; } // [END configure_firebase]
// [START set_messaging_delegate] [FIRMessaging messaging].delegate = self; // [END set_messaging_delegate]
RCTBridge bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; RCTRootView rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"eXpanded" initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible];
// #################################### if ([UNUserNotificationCenter class] != nil) { // iOS 10 or later // For iOS 10 display notification (sent via APNS) [UNUserNotificationCenter currentNotificationCenter].delegate = self; UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError _Nullable error) { // ... }]; } else { // iOS 10 notifications aren't available; fall back to iOS 8-9 notifications. UIUserNotificationType allNotificationTypes = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge); UIUserNotificationSettings settings = [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil]; [application registerUserNotificationSettings:settings]; }
[application registerForRemoteNotifications]; // ####################################
// Define UNUserNotificationCenter UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self;
return YES; }
(NSURL )sourceURLForBridge:(RCTBridge )bridge {
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
}
(void)messaging:(FIRMessaging )messaging didReceiveRegistrationToken:(NSString )fcmToken { NSLog(@"FCM registration token: %@", fcmToken); // Notify about received token. NSDictionary *dataDict = [NSDictionary dictionaryWithObject:fcmToken forKey:@"token"]; [[NSNotificationCenter defaultCenter] postNotificationName: @"FCMToken" object:nil userInfo:dataDict]; // TODO: If necessary send token to application server. // Note: This callback is fired at each app startup and whenever a new token is generated. }
// Receive displayed notifications for iOS 10 devices. // Handle incoming notification messages while app is in the foreground.
(void)userNotificationCenter:(UNUserNotificationCenter )center willPresentNotification:(UNNotification )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { NSDictionary *userInfo = notification.request.content.userInfo;
// With swizzling disabled you must let Messaging know about the message, for Analytics [[FIRMessaging messaging] appDidReceiveMessage:userInfo];
// Print message ID. if (userInfo[kGCMMessageIDKey]) { NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]); }
// Print full message. NSLog(@"%@", userInfo);
// Change this to your preferred presentation option completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionAlert); }
// Required to register for notifications
// Required for the register event.
// [START receive_message] // Required for the notification event. You must call the completion handler after handling the remote notification.
(void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // Print message ID. if (userInfo[kGCMMessageIDKey]) { NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]); } // Print full message. NSLog(@"%@", userInfo);
completionHandler(UIBackgroundFetchResultNewData);
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; } // [END receive_message]
// Required for the registrationError event.
@end `
I have the same error with v1.7.1. willPresentNotification
is not triggering.
- AppDelegate.h
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UNUserNotificationCenter.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
@property (nonatomic, strong) UIWindow *window;
@end
- AppDelegate.m
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}
@lowell-list-cambia For me, this error keeps popping up. Any idea what could cause this?
In the JS part, i am using react-native-push-notifications
onNotification: (notification) => {
// console.log("NOTIFICATION:", notification);
// process the notification
// call notification.finish
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
AppDelegate.m
// Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
// Still call the JS onNotification handler so it can display the new message right away
NSDictionary *userInfo = notification.request.content.userInfo;
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo
fetchCompletionHandler:^void (UIBackgroundFetchResult result){}];
// hide push notification
completionHandler(UNNotificationPresentationOptionNone);
}
Error
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSObject userNotificationCenter:willPresentNotification:withCompletionHandler:]: unrecognized selector sent to instance 0x2817366a0'
terminating with uncaught exception of type NSException
These are my dependencies:
react-native - 0.63.3 react- 16.13.1 react-native-push-notification - 7.0.0 @react-native-community/push-notification-ios - 1.8.0
onNotification gets triggered and willPresentNotification get triggered. But, I still notification doesn't get showed when app is in foreground. In background everything works fine...
I still can't get foreground notifications to work:
@kyytiPetteri I followed every instruction to the T several times over, and still couldn't get it to work. After a day and a half of messing around, I right-clicked
userNotificationCenter
to jump to its definition so I could have a look. Much to my surprise, it presented two definitions. One of which was RNFB.🎉 Instant clarity! I've upgraded from RN 0.59 to 0.61.5 months ago, and then to 0.62.2 recently. React Native Firebase (which I only use for Android...) had auto-linked into my iOS build.
I skipped auto-linking for the related packages, nuked and reinstalled my pods, and my foreground notifications now work as intended again.
Your answer helped me a lot. In my case, I was using "react-native-firebase": "^5.6.0",
as an additional dependency for some reason that i really don't know.
So,
"react-native-firebase": "^5.6.0"
from package.jsonSOLVED THE PROBLEM. Now am getting the notification event fired.
I follow ios basic installation guide as in the documentation here. For you with issue willPresentNotification not firing in AppDelegate.m, I follow this answer and works.
If you use react-native-push-notification, using firebase messaging to send the notification, and using onNotification with this strategy, try to exclude gcm.message_id, fcm_options, and google.c.a.e field from userInfo when you want to show in foreground.
function showNotification(notifId, data) {
let notifData = {
id: notifId,
...data,
}
if (Platform.OS === 'ios') {
/* iOS only properties */
const {
fcm_options: fcmOptions,
'gcm.message_id': gcmMessageId,
'google.c.a.e': googleCAE,
...otherUserInfoData
} = notifData.userInfo
notifData = {
...notifData,
userInfo: {
...otherUserInfoData,
},
}
}
PushNotification.localNotification(notifData)
}
PushNotification.configure({
onNotification(notification) {
if (notification.userInteraction) {
navigateFromNotification(notification.data)
} else if (notification.foreground) {
showNotification(notification.id, notification.data)
}
// (required) Called when a remote is received or opened, or local notification is opened
notification.finish(PushNotificationIOS.FetchResult.NoData)
},
}
Background and quit state are working well in android and ios. Only foreground ios not showing. My Stack :
It seems to be that we are all lost and we'll continue to be until this issue is well documented! I'm using RN v0.63 and had the same issues that everyone is having here and in other 14506 issues on this repo and on react-native-push-notification. The problem in the documentation lies in the integration between both libs.
Tested with: react-native: 0.63 @react-native-community/push-notification-ios: 1.8.0 react-native-push-notification: 7.2.0 Using Firebase Cloud Messaging (FCM) for android & ios
The solution:
onNotification
to trigger on foreground (which wasn't the case for ios - android worked fine).completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
instead of:
completionHandler(UNNotificationPresentationOptionNone);
because it seems that using UNNotificationPresentationOptionNone
hides locally triggered notifications too.Notes:
PushNotification.localNotification(...)
inside onNotification
- because only then you will have a choice if to show or not.onNotification
(it will re-trigger onNotification
), I just used a local notification marker in the notification data and did what @robbycp said (removing irrelevant props from the notification).channeId
for android local notifications to work.I'll be posting it on react-native-push-notification
also.
Please note that
UNUserNotificationCenter
is available in iOS 10+, so if your app needs to support iOS 9, you'll need to wrap appropriate parts of code in conditional blocks. More aboutUNUserNotificationCenter
in the documentation: https://developer.apple.com/documentation/usernotifications/unusernotificationcenter?language=objc
AppDelegate.h
1. Add new import to the imports section in the top of the file `#import <UserNotifications/UserNotifications.h>` 2. Declare that your app implements `UNUserNotificationCenterDelegate` in `@implements` block
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate> // Add UNUserNotificationCenterDelegate to the list, in my case it looks like this
AppDelegate.m
1. Add new import to the imports section in the top of the file `#import <UserNotifications/UserNotifications.h>` 2. Add following code to the bottom of `didFinishLaunchingWithOptions` method (before return):
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self;
1. Add `willPresentNotification` method. Code below will present all notifications in the foreground.
// Manage notifications while app is in the foreground - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge); }
In the
willPresentNotification
method you can control which notifications to show. I.e. in our app we only present one type of notifications in the foreground. The type of notification is added to apns payload. Example:// Manage notifications while app is in the foreground - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { NSDictionary *userInfo = notification.request.content.userInfo; // read apns payload NSString *notificationType = userInfo[@"notificationType"]; // check your notification type if (![notificationType isEqual: @"some custom type"]) { // we silence all notifications which do not match our custom notification type completionHandler(UNNotificationPresentationOptionNone); return; } // custom notification type is displayed normally completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge); }
Hope this helps
this just works great 💯
For those of you upgrading from version 1.1.1 to 1.2.0 please be aware that there was some breaking changes introduced (and not yet documented with how foreground notifications are handled. Specifically, before 1.2.0, native notifications would not be handled if app was in foreground and now they are. If you'd like to keep legacy behavior, I recommend changing your willPresentNotification as follows:
//Called when a notification is delivered to a foreground app. -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { //Still call the javascript onNotification handler so it can display the new message right away NSDictionary *userInfo = notification.request.content.userInfo; [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo]; //hide push notification completionHandler(UNNotificationPresentationOptionNone); }
if I ever see you in person, I'll definitely give you a treat. man! you saved me from a terrible headache. thank you!
For those of you upgrading from version 1.1.1 to 1.2.0 please be aware that there was some breaking changes introduced (and not yet documented with how foreground notifications are handled. Specifically, before 1.2.0, native notifications would not be handled if app was in foreground and now they are. If you'd like to keep legacy behavior, I recommend changing your willPresentNotification as follows:
//Called when a notification is delivered to a foreground app. -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { //Still call the javascript onNotification handler so it can display the new message right away NSDictionary *userInfo = notification.request.content.userInfo; [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo]; //hide push notification completionHandler(UNNotificationPresentationOptionNone); }
I've spent weeks thinking what was wrong with my code even though I followed the examples thoroughly. I can't believe this is not documented yet. Thanks man! You saved me 👍 🎉 !
I would like to share a solution that I found with notifications in the foreground for iOS ... lines below my AppDelegate.m
import "AppDelegate.h"
import <React/RCTBundleURLProvider.h>
import <React/RCTRootView.h>
import <ReactNativeNavigation/ReactNativeNavigation.h>
import
@import Firebase;
@implementation AppDelegate
(BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions {
if ([FIRApp defaultApp] == nil) { [FIRApp configure]; }
// Define UNUserNotificationCenter UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self;
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; [ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions];
return YES; }
//Called when a notification is delivered to a foreground app. -(void)userNotificationCenter:(UNUserNotificationCenter )center willPresentNotification:(UNNotification )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge); }
// Required to register for notifications
(void)application:(UIApplication )application didRegisterUserNotificationSettings:(UIUserNotificationSettings )notificationSettings { [RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings]; } // Required for the register event.
(void)application:(UIApplication )application didRegisterForRemoteNotificationsWithDeviceToken:(NSData )deviceToken { [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } // Required for the notification event. You must call the completion handler after handling the remote notification.
(void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; } // Required for the registrationError event.
(void)application:(UIApplication )application didFailToRegisterForRemoteNotificationsWithError:(NSError )error { [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error]; } // Required for the localNotification event.
(void)application:(UIApplication )application didReceiveLocalNotification:(UILocalNotification )notification { [RNCPushNotificationIOS didReceiveLocalNotification:notification]; }
(NSURL )sourceURLForBridge:(RCTBridge )bridge {
if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
endif
}
@end