didReceiveRemoteNotification no called in background although content_available = true - ios

I use push notification in my app ,It is work fine but I want to receive notification if my app in background but method didReceiveRemoteNotification not called
I mad that
1- enable Background Mod
2- check remote notification
3- put content_available = true in data payload
and also when I test it from fcm dashboard not work ,
Please can anyone help me , Thanks.

If you're testing on iOS 10, content_available must be in JSON value of notification key, not in data key. Although for iOS <= iOS 9, content_available can be in JSON value of data or notification.

There's a typo in your code. It's not "content_available", the correct key is "content-available".
When you send "content-available" = 1, didReceiveRemoteNotification will be called.

You app needs to handle all the possible push notification delivery states:
Your app was just launched
Your app was just brought from background to foreground
Your app was already running in the foreground
You do not get to choose at delivery time what presentation method is used to present the push notification, that is encoded in the notification itself (optional alert, badge number, sound). But since you presumably are in control of both the app and the payload of the push notification, you can specify in the payload whether or not there was an alert view and message already presented to the user. Only in the case of the app is already running in the foreground do you know that the user did not just launch your app through an alert or regularly from the home screen.
You can tell whether your app was just brought to the foreground or not in didReceiveRemoteNotification using this bit of code:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateActive )
// app was already in the foreground
else
// app was just brought from background to foreground
...
}
for further reference. Please check
didReceiveRemoteNotification when in background

Related

Send silent notification to my iOS app in background, through FCM message console

I want to send silent notifications to my iOS app, for which i have implemented FCM into it. while app is in background, i need to perform some operation when app gets the notification from the FCM .
for that ,execution process will enter into the method called
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
but problem is that, it does not enter into this method until user taps on the notification .
As per (FCM documents) , if we want to wake up our app in background then we have to pass content_available parameter with key value true . but when i am sending this information through your FCM Compose message console in custom data, our app is not waking up nor getting activated in background, until user taps on the notifications. I guess the notifications which all i am receiving are normal notifications, not silent one . so FCM implementation and sending notification is working perfectly it seems.
i have followed all the FCM documents given and referred almost all possible connected stackoverflow solutions . even i have followed apple documents for sending remote notifications . and lastly i am sending "content_available" : true through FCM message console. but it is not becoming silent notification and i am receiving notification as normal notification which user has to tap on, to enter into the method didReceiveRemoteNotification.
i have referred many links like these
here,
here, &
here
is it even possible through FCM to receive notifications in backgrounds (like silent notifications) or not ?
or any other way to implement it ?
i have got the solution for this .
just follow this link and its answer .
and enter the json body like this in postman
{
"to":"eEBrg.... .... .... .... (FCM Token)",
"priority": "normal",
"content_available": true,
"notification":{
(do not send body here if you want to send the silent notification)
"requesttype":"ring" // optional
}
}
... and your app will wake up in background and will enter into the method didReceiveRemoteNotification .

iOS doesn't receive Push notification when the app is being killed

I have found similar questions on Stack Overflow, but none of them have cleared the point.
I am using Firebase Cloud Messaging for sending push notifications in my app. I am storing the messages received in a local database. When my app is active or in the background, my app is able to receive the notifications (delegate methods called properly) but if the app is being forced quit or not in the memory then also the device is receiving the notifications and sat in notification center but the none of the delegate methods called when the app is being launched by an icon. If a user clicks on Message in the notification center, then the app gets launched, but only the message clicked on is being received and not all of them (in the case of multiple notices have been received).
According to Apple - The system does not automatically launch your app if the user has force-quit it. In that situation, the user must relaunch your app or restart the device before the system attempts to launch your app automatically again.
But even if the user launched the app still not receive the notifications which were received and sat in the notification center.
Here are the points followed by the app:
My app has no VoIP functionality.
Content-available has been set to 1.
Has enabled to receive background remote notifications.
All notifications sent has been received and displayed in the notification center.
{
aps = {
alert = {
body = "Push Notification Test Message";
title = Push Notification;
};
badge = 1;
"content-available" = 1;
sound = default;
};
"gcm.message_id" = "0:1499340350307980%361a2e5b361a2e5b";
m = "Push Notification Test Message";
tag = m;
}
If the app is being forced quit or not in memory then your app will not receive silent notifications(i.e. Content-available set to 1).
Only push notifications are received in above conditions.
If user clicks on Message in notification center, then app gets launched and only that clicked the message will be received in delegate methods.You cannot access all the messages in the notification tray.
There is no way to get push notifications for the application if app is not running. This is restriction . You are only can get and clear local notifications. So the another way of resolving your problem is saving your notification on the backend when you send it. Then after launching app , you can get notifications list from the server , and match it with id . You can send any parameters that you want in notification playload.
Your app should not rely on the delivery of push notifications. Delivery of push notifications is not guaranteed, as you have found.
Even if your app isn't terminated you may not receive all notifications; For example if the device is in airplane mode and multiple notifications are sent, only the last one is delivered when the device comes back online.
Your app should check with the server for new messages when it is launched or when a notification is received in order to "catch up".
You can also consider including a message payload in your silent notifications. This will be displayed to the user if your app is terminated to prompt them to open your app.
You need to handle method for push notification when the application is open from a tap on any notification. As soon as you tap on notification application will awake and lunch it.
In didFinishLaunchingWithOptions, you need to put below condition:
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithDictionary:[launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey]];
}
It also called below method when notification is tapped:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
}

Execute few lines of code when received silent push notification and app is running in background, ios

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
NSLog(#"PUSH NOTIFICATION %#",userInfo);
if([userInfo[#"aps"][#"content-available"] intValue] == 1){
NSLog(#"SILENT PUSH NOTIFICATION");
//Here I'm inserting a flag value to my DB.
completionHandler(UIBackgroundFetchResultNewData);
}
else{
NSLog(#" GENERAL PUSH NOTIFICATION ");
completionHandler(UIBackgroundFetchResultNoData);
}
}
My silent notification payload is {
aps = {
"content-available" = 1;
sound = "";
};
}
To support I have added a key in info.plist in "Required background modes"
item 0 = App downloads content in response to push notifications
Also in capabilities section my Background Modes are ON with remote notification check mark is selected.
Now my question is when I run my app then I'm able to receive silent as well as general push notification and code is executing successfully in foreground mode but when I press home button (not forcefully quitting by swiping it away and also device's passcode lock is open) my app is going to background mode and then my code is not executing even I'm able to receive push notifications those are having alert and sound, but app is not launching in background mode.
I'm thinking that for foreground and for background mode whenever my app is receiving any push notification don't matter is it silent or general push notification my first log in the delegate method should have to print on the console i.e NSLog(#"PUSH NOTIFICATION %#",userInfo);
Please help I'm struggling with this since last 2-3 days.
My info.plist
I am doing almost exactly the same thing as you except I use the silent push notifications to present a local notification when the app is in the background and use it to update some state when the app is in the foreground. I am NOT registering for background fetch, only "remote-notification".
#Paulw11 is correct that you need to call the completionHandler each time didReceiveRemoteNotification is called.
I would check your plist to make sure your background modes are configured correctly. Maybe you could post the contents of your plist.
My notification payload looks exactly the same as yours so I don't think that is the problem. I initially had issues because the payload wasn't exactly right.
Keep in mind that if you kill the app (swipe it away), you will not get silent push notifications until the app is restarted.
I think you need to test once with 'content-available' outside 'aps', like the following:
aps = {
alert = "This is test alert";
badge = 1;
};
"content-available" = 1;

Apple push notification info is missing when we clear the notifications

I have received push notification, if i open the push notification then didReceiveRemoteNotification is calling and i am getting the notification information, instead of if i clear the notifications and open the app then didReceiveRemoteNotification is not getting called. How to resolve this?
If you open the app from the launch icon (instead of opening it from the push notification), didReceiveRemoteNotification will not be called and you'll have no way to access the notification data. It doesn't matter if you clear the notifications or not.
If the action button is tapped (on a device running iOS), the system launches the application and the application calls its delegate’s application:didFinishLaunchingWithOptions: method (if implemented); it passes in the notification payload (for remote notifications) or the local-notification object (for local notifications).
If the application icon is tapped on a device running iOS, the application calls the same method, but furnishes no information about the notification.
As Eran pointed out, if You're opening the app from the Icon that callback will not be called. I don't know if the notification is totally removed when You delete it from the notification center list, but if the app is not running and has been launched by tapping on the notification, you can check for the notification in the launchOptions at the startup:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary
*)launchOptions {
NSDictionary *notif = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
if (notif) {
//handle your notification here
}
return YES;
}

Receiving Push Notifications while in background

I know this is covered in a lot of places, but I cannot figure this out. I use Urban Airship for push notifications. Everything seems to be fine except that when my app is in the background - didReceiveRemoteNotification is not getting called. It works when in the foreground - I am able to properly process messages. And I am able to get to messages from launch options if message is tapped from notifications center. But when in the background, a message it send - iOS displays the alert - didReceiveRemoteNotification is not called. When I tap on my Application icon (not from within notification center) the app comes to the foreground and I have no idea the notification is present. Any ideas?
application:didReceiveRemoteNotification: will call in the background only when you have added content-available key with value 1 into the notification payload.
In case of the Urban Airship, you can send Test Push under the Setting tab.
Sample Payload for Push Notifications:
{
"aps": {
"alert": "aaaa",
"badge": "+1",
"content-available": "1"
},
"device_tokens": [
"86BA71E361B849E8312A7B943BA6B26A74AB436381CF3FEE3CD9EB436A12A292"
]
}
Apple has clearly mentioned in his documentation....
For a push notification to trigger a download operation, the
notification’s payload must include the content-available key with its
value set to 1. When that key is present, the system wakes the app in
the background (or launches it into the background) and calls the app
delegate’s
application:didReceiveRemoteNotification:fetchCompletionHandler:
method. Your implementation of that method should download the
relevant content and integrate it into your app.
https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
From the APNS programming guide :
Let’s review the possible scenarios when the operating delivers a
local notification or a remote notification for an application.
The notification is delivered when the application isn’t running in the
foreground. In this case, the system presents the notification,
displaying an alert, badging an icon, perhaps playing a sound.
As a result of the presented notification, the user taps the action button
of the alert or taps (or clicks) the application icon. If the action
button is tapped (on a device running iOS), the system launches the
application and the application calls its delegate’s
application:didFinishLaunchingWithOptions: method (if implemented); it
passes in the notification payload (for remote notifications) or the
local-notification object (for local notifications).
If the application icon is tapped on a device running iOS, the application
calls the same method, but furnishes no information about the
notification.
I believe the last sentence describes your case, and explains why your application gets no information about the notification.
didReceiveRemoteNotification is calling ONLY if app in foreground or if app is just launched or is bought from background to foreground
link in Apple and some question
Method didFinishLaunchingWithOptions:(NSDictionary *)launchOptions parameter launchOptions one of the dictionary keys are UIApplicationLaunchOptionsRemoteNotificationKey which holds the pressed push notification info.
You can push received info after tour main root controller is initialised. I save it to some property and then push it after view is initialised.
if (launchOptions) {
if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]) {
self.notificationToMakeAction = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
}
}

Resources