IOS App implementing Google Cloud Messaging receives notifications only when active - ios

I have implemented in my IOS app the new Google Cloud Messaging framework for handle push notifications. After implementation I'm able to receive push notifications only when App is active and in foreground. If App is closed or in background I didn't get the notification alert in my device. In the iOS notifications settings I see my app enabled to receive them.

I was having a similar problem where the app would receive a notification only if the app was running (foreground/background) and wouldn't receive anything if app was killed manually (terminated)
All I had to do to fix that was to add priority & content_available to the notification body when sending it (as #KayAnn pointed out)
Here's how it should look like :
{
"to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
"content_available" : true,
"priority": "high",
"notification" : {
"body" : "Winter is coming!",
"title" : "John Snow"
}
}
Keep in mind that I also have UIBackgroundModes: remote-notification in Info.plist.

Google documentations (in step 4) quotes:
If the GCMExample application is running in the foreground, you can
see the content of the notification printed to the Xcode debug
console; if the GCMExample app is in the background, you will receive
an APNS notification.
So in order to receive messages when the app is in background you have to register APNS as options as below as described here.
_registrationOptions = # {
kGGLInstanceIDRegisterAPNSOption: deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption: #YES
};
EDIT:
There are few other things you need to do:
1) While publishing the app move to production certificate
In the JSON Payload:
2) Use "content_available": "true" OR
3) Set the "priority": "high"
EDIT:2
Using content_available and priority high in the same payload conflicts with Apple's recommendation (Apple docs). I have come across this during my testing. In such a scenario the message may be throttled.
Use either / or of these two parameters instead.
A Tip on working use-cases:
- content_available: use when you are sending data only and do not have other notification specific parameters like alert, badge, sound etc. This is because by default a content_available message is a silent push.
- Priority: high: Use it when you are sending a notification which should reach the users immediately, i.e time critical notifications such as game scores.

Related

Activate iOS Application when remote notification with data is received

I'm creating an iOS application for two factor authentication.
I have a system where the user logs in and my server sends a challenge via remote notification (push message) to my iOS app.
I am able to receive the push notification when the app is not activated, so that's fine.
What I am not able to do is to activate my app. I don't know how to do it.
The push message contains structured data (not a simple alert text message).
Is it possible? Can I set some flag in the push message? Or is this one of those things that violates iOS guidelines?
go to App Settings -> Capabilites and turn on Background Modes for your app. Check the last option, Remote Notifications,
to know more about it check this tutorial :
This raywenderlich tutorial is all u need to get up and running with push notification
if that didn't work add : 'content_available' => true to your push notification parameters
ex :
{
"alert" :"",
"badge" :"787",
"Content-available" : "1" // or true,
"sound" : ""
}
If you provide this key with a value of 1, (if user opens you app is in background or resumed) the application:didReceiveRemoteNotification:fetchCompletionHandler: will be called.
According to RemoteNotifications Programming content-available definition is
Provide this key with a value of 1 to indicate that new content is available. Including this key and value means that when your app is launched in the background or resumed, application:didReceiveRemoteNotification:fetchCompletionHandler: is called.(Newsstand apps are guaranteed to be able to receive at least one push with this key per 24-hour window.)
You can refer to Apple Documentation about Creating the Remote Notification PayLoad and look for "Configuring a Background Update Notification". Just keep in mind this will not work if your application is force quit. Make sure your application is showing in AppSwitcher but in an inactive mode means you haven't used from a long time.

Is there a way to receive notification when app is killed? That is when app is not working in foreground or background in iOS

I am using APNS push with content-type = 1. I receive the payload and fire using local notification.
this works fine in background and foreground mode
but when app is killed I get nothing.
what is the solution? I have seen people saying something about VOIP apps
but mine is not a VOIP app..
Some said to check Pushkin framework?
Any guidance?
Update
with this Json format I received notification when app was in killed state.. I checked on lower version 9.3 iOS.. have to check on iOS 11..
{
"aps": {
"content-available": 1,
"alert": "custom message ",
"badge": 1,
"sound": "solemn.wav"
},
"id": "55",
"data": "your data"
}
I don't think it can be done if your app is not a VOIP app. But, if you want to change the appearance of a push notification, you may want to look at the Notification Service Extension.
You have to include mutable-content flag as 1 in your payload inside aps. You cannot use content-type flag with this notification. Also, you have to show user something or the other after you have received the payload. Also, it is available in iOS 10 and above only.
Even with all these constraints, you can do some amazing things with this extension which were not possible earlier.
You can now show media attachment in the notification.
You can download small content or hit an API.
You can modify earlier sent push notification.
You can create a local notifcation center in your app.

iOS 10 Firebase Notification not showing on background

I´m having trouble on receiving push notifications (background) on a specific device running iOS 10. Other phones with iOS 9 are doing fine.
Although if I open the app the notification shows a banner that I implemented. Why does not show anything in background state?
Reading the firebase documentation something made me a little confused
According to a github firebase example on the following link https://github.com/firebase/quickstart-ios/blob/master/messaging/FCMSwift/AppDelegate.swift, there is a comment in the didReceiveRemoteNotification method that says:
// If you are receiving a notification message while your app is in
the background, // this callback will not be fired till the user taps
on the notification launching the application. // TODO: Handle data of
notification
So it my app is in background, does not apple do the whole thing to make that default iOS notification?
Does the content_available value interfere on this? I also send notification and data values.
Here is an example of the JSON I send:
{
"content_available": true,
"priority": "high",
"data": {
"post_id": "...",
"push_id": "..."
},
"notification": {
"title": "...",
"body": "..."
},
"registration_ids": ["xxxx"]
}
The expected behaviour would be:
App dead: the system will show the notification
App background: the system will show the notification and call the didReceiveRemoteNotification method.
App active: the system will NOT show de notification and call the didReceiveRemoteNotification method.
Right?
Your assumptions are correct except for number 2. There are several cases where apple will not call didReceiveRemoteNotification you even if you set the content_avaialable.
1) Device has low battery and is in power saver mode
2) App has "background app refresh" disabled
3) Other undocumented scenarios where apple decides not to wake up your app. Apple reserves the right to not deliver notifications for performance reasons.
Having said that, if the user taps the notification you will always get the payload in didReceiveRemoteNotification.

It is possible to process remote notifications and avoid showing it to the user?

I have an application in iOS that receives push notifications through GCM (Google Cloud Messaging) and APNS . These notifications contain some data that has to be processed before showing anything to the user.
After data processing, I generate a local notification with proper information to the user.
I see this behaviour:
With the app in foreground I only see the local notification.
With the app in background I see both notifications, remote and local.
With the app not even running, no notification is shown.
Can I show only my local notification after processing some data? (at least when the app is in background)
I have read about using content-available property as documented here, but the behaviour is almost the same.
Finally I get the solution (thanks to #DmytroShvecov for the pointer).
It is necessary to follow the official documentation here and follow these steps in the server:
Include inside aps keys alert, badge and sound but with blank value.
Include content-available key with 1 as value (if you want your notifications to be processed in background without interaction of the user.
Include any acme key to be treated as custom payload with your data.
This is an example of everything working together:
{
"aps": {
"alert": "",
"badge" : "",
"sound":"",
"content-available": 1
},
"acme": {
"what": "ever",
"you": "want"
}
}

The purpose of "Content-available" in Push Notification Json?

The purpose is to send push notification with only badge value & nothing else (no banner).
I integrated parse sdk to test push notification & send this push notification
{
"alert" :"",
"badge" :"787",
"Content-available" : "1",
"sound" : ""
}
So the push notification got send when app is in background, foreground & when app is killed.
The purpose to wipe some data on arrival of push notification with badge valve 78 got succeeded.
I send same notification with "Content-available" : "1" removed but everything worked fine as earlier.
My understanding on "Content-available" was that putting it's value to 1 will allow push notification with no alert value.
So I am confused or I am missing something to know the meaning of "Content-available" in this push notification JSon.
Thanks
If you provide this key with a value of 1, (if user opens you app is in background or resumed) the application:didReceiveRemoteNotification:fetchCompletionHandler: will be called.
According to RemoteNotifications Programming content-available definition is
Provide this key with a value of 1 to indicate that new content is
available. Including this key and value means that when your app is
launched in the background or resumed,
application:didReceiveRemoteNotification:fetchCompletionHandler: is
called.
(Newsstand apps are guaranteed to be able to receive at least one push
with this key per 24-hour window.)
TL;DR:
"content-available" : 0: The default; your application won't be notified of the delivery of the notification unless the app is in the foreground.
"content-available" : 1: your application will be notified of the delivery of the notification if it's in the foreground or background (the app will be woken up).
The only time you need to use "content-available" : 1 is for background update notifications:
Background update notifications improve the user experience by giving you a way to wake up your app periodically so that it can refresh its data in the background. When apps do not run for extended periods of time, their data can become outdated. When the user finally launches the app again, the outdated data must be replaced, which can cause a delay in using the app. A background update notification can alert the user or it can occur silently.
However, this does NOT always mean that this notification will be invisible to the user:
If there are user-visible updates that go along with the background update, you can set the alert, sound, or badge keys in the aps dictionary, as appropriate.
By default, "content-available" is set to 0. These "regular" notifications do not immediately notify the app UNLESS the app is in foreground. Instead, these "regular" notifications notify the app when a user taps on them or has selected an option via a "Haptic Touch" on the notification.
Background update notifications are delivered to application(_:didReceiveRemoteNotification:fetchCompletionHandler:):
Unlike the application(_:didReceiveRemoteNotification:) method, which is called only when your app is running in the foreground, the system calls this method when your app is running in the foreground or background.
Note: there's a key distinction between "your application" and "the device:" the device will show the notification if the payload requests it to be shown, but this doesn't always mean that "your application" will be notified on the delivery of this notification (aka "your application" code will run). That's where "content-available": "1" comes in: "your application" will always be notified unless its been terminated.
Short answer: for me I just used "content_available" : "1", or "content_available" : true for resume the background/quit modes in iOS. Notice in my case it's underscore and not hyphen separated.
In my specific scenario my app was made in react-native and I have used https://rnfirebase.io for push notifications
Here a complete explanation of this:
https://rnfirebase.io/messaging/usage#data-only-messages
in IOS
content_available" : "1
equivalent in Android
priority: 'high',
In both cases the background message will invoke the onMessage() method when the app is resumed from background, so the program can run some specific code from there.
Here a sample of sending a push notification using CURL:
#curl -H "Content-type: application/json" -H "Authorization:key=#MyAuthHashCode#" -X POST -d '{ "to": "/topics/#thetopicnumber#","notification": { "title": "msg for topic", "body": "bodytext", "content_available": "true" }}' https://fcm.googleapis.com/fcm/send

Resources