ios
ios copied to clipboard
Scheduled notifications are not handled when app is killed
Description
When I open a scheduled notification when the app is killed, the app opens and nothing happens. When I open a scheduled notification when the app is in foreground or background, the notification is handled.
This is the notification data I get when I open the app by tapping on a notification:
notification ios {"action": undefined, "badge": 0, "data": null, "finish": [Function finish], "fireDate": 1610466763000, "foreground": false, "id": undefined, "message": undefined, "reply_text": undefined, "soundName": "default", "title": undefined, "userInteraction": false}
I think there must be something wrong with the App Delegate but I followed the instructions and checked with the example provided.
AppDelegate.h
#import <UserNotifications/UNUserNotificationCenter.h>
...
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
...
AppDelegate.m
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>
#import "RNBootSplash.h"
...
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
...
@implementation AppDelegate
// 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 localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
}
...
// Define UNUserNotificationCenter
UNUserNotificationCenter *center =
[UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
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(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
@end
React Native version:
SDKs:
iOS SDK:
Platforms: iOS 13.7, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
npmPackages:
@react-native-community/cli: Not Found
react: 16.13.1 => 16.13.1
react-native: 0.63.4 => 0.63.4
@react-native-community/push-notification-ios": "^1.8.0"
Steps To Reproduce
- Schedule a local notification
- Kill App
- Open scheduled notification
Expected Results
The notification should be handled
+1
Any workaround?
I didn't find one yet...
Same problem :(
@Estebank94 Are you opening the notification through an action on the notification or just by tapping the notification?
Also, what do you mean the notification should be handled? By what?
@ninjz do you know how I can handle an action when the app is killed, or is it not possible? Since the event listener is removed
@joaocosta9 Two things:
- Make sure you're not using
react-native-splash-screen
as that ends up swallowing some events which prevents you from receiving the callbacks on the delegate. (This was a huge breakthrough for me which took days to figure out) - Since
getInitialNotification()
always returns null. Store the notification action response indidReceiveNotification
callback inside of AsyncStorage and retrieve that on app launch. Also, delay the call of the callback inside ofdidReceiveNotification
to make sure there is enough time to handle everything you need to process the notification action.
For me, the biggest issue now is getting this to work with the Watch. Can't seem to consistently get the notification action response from it when the app has been backgrounded for some time (> ~30mins). Still investigating this issue and my guess so far is that it's due to some other dependency.
Hey @ninjz , thanks for your response. You are talking about the didReceiveNotificationResponse in the AppDelegate.m file correct?
@joaocosta9 Yes, if you set the AppDelegate as the delegate for the UNUserNotificationCenter.currentNotificationCenter
I would really appreciate if somebody could share the code on how to store the didReceiveNotification response in the AsyncStorage
@cuttlas me too, I tried to find a way to do that, but I could not find one. Im sorry @ninjz, is there any way you can help us with this ? 😅
@joaocosta9 Two things:
- Make sure you're not using
react-native-splash-screen
as that ends up swallowing some events which prevents you from receiving the callbacks on the delegate. (This was a huge breakthrough for me which took days to figure out)- Since
getInitialNotification()
always returns null. Store the notification action response indidReceiveNotification
callback inside of AsyncStorage and retrieve that on app launch. Also, delay the call of the callback inside ofdidReceiveNotification
to make sure there is enough time to handle everything you need to process the notification action.For me, the biggest issue now is getting this to work with the Watch. Can't seem to consistently get the notification action response from it when the app has been backgrounded for some time (> ~30mins). Still investigating this issue and my guess so far is that it's due to some other dependency.
@ninjz do you have any progress with this?
+1