I'm working with firebase to add push notification feature to an app, everything is fine with the push notification it self but in some state of the app the push notification is not receive.
Foreground / Background:
{
"data":{
"title": "title",
"message": "message"
},
"content_available":true,
"priority":"high",
"registration_ids":[
""
]
}
The problem comes when the app is killed by the user, I send the same http request but the app didn't receive the remote notification.
I was testing with the console on firebase and when the app is killed the notification it's receive but I couldn't replicate the console request to http request
this is the content of notification when I made it through firebase console
[
"google.c.a.c_l": label optional,
"google.c.a.e": 1,
"google.c.a.ts": IntValue,
"google.c.a.udt": 0,
"gcm.n.e": 1,
"aps": {
alert = {
body = mensaje;
title = title;
};
},
"google.c.a.c_id": IntValue,
"gcm.message_id": 0:1502103735577088%9218dc2f9218dc2f
]
This is how iOS works, basically. When your app is killed by the user, it no longer receives background notifications.
Here's a somewhat-old-but-still-accurate link with some more detailed information: http://samwize.com/2015/08/07/how-to-handle-remote-notification-with-background-mode-enabled/
Related
We are building a react-native IOS application, which uses FCM at the backend and notifee at the front end. Everything works, but there are often times when a FCM-data-push is sent but the notification is not shown on IOS if the app is in killed state. Following is the message object that we are sending to the FCM server through firebase-admin's node package.
const message = {
token: fcmToken,
data: prepared,
android: {
priority,
},
apns: {
payload: {
headers: {
'apns-priority': 10,
'apns-push-type': 'background',
},
aps: {
'content-available': 1,
},
},
},
};
It is required to register a task that runs in the background while the app is killed then the registered task handle notification event listens and pushes notification.
Consult this package for background task - https://www.npmjs.com/package/react-native-background-task
TL;DR
I'm detecting uninstalls using FCM. If I receive a NotRegistered token on sending notification, I assume that the app has been uninstalled.
Everything works fine with Android, while on IOS I'm always getting a success response, even if the app has uninstalled for days.
More info
I have read that it is possible to detect uninstalls using APNs feedback Service, where Apple reports any inactive tokens.
Also I read on Firebase official documentation that:
content_available - On iOS, use this field to represent content-available in the APNs payload. When a notification or message is sent and this is set to true, an inactive client app is awoken, and the message is sent through APNs as a silent notification and not through the FCM connection server.
In order to send notifications via APN, I have tried to send push notifications using content_available: true, but I cannot reproduce a NotRegistered token error on IOS. It still returns a success message.
I'm sending notifications using sendMulticast. my payload:
const payload = {
notification: {
title: text,
},
android: {
priority: "high",
ttl: 60 * 60 * 1,
collapseKey: "yo",
notification: {
channel_id: 'YO',
tag: userDoc.id,
},
},
apns: {
payload: {
aps: {
sound: "reminder.caf",
"content-available": 1,
}
},
headers: {
"apns-collapse-id": "yo",
"apns-priority": "10"
}
},
priority: 10
}
I also cannot reproduce a NotRegistered token response via an HTTP request:
curl -X POST \
https://fcm.googleapis.com/fcm/send \
-H 'authorization: key=server_key_here' \
-H 'content-type: application/json' \
-d '{
"to": "fcm_token_here",
"priority": "high",
"content_available": true,
"notification": {
"empty": "body"
},
"data": {
"key1": ""
}
}'
Bottom Line
1. How do I detect IOS uninstalls using FCM?
2. And if it's not possible, how can I detect uninstalls on IOS?
Well, depends on your demand. Your questions's answer is slient push not normal push.
A background notification is a remote notification that doesn’t display an alert, play a sound, or badge your app’s icon. It wakes your app in the background and gives it time to initiate downloads from your server and update its content. Apple Document
Important
The system treats background notifications as low priority: you can use them to refresh your app’s content, but the system doesn’t guarantee their delivery. In addition, the system may throttle the delivery of background notifications if the total number becomes excessive. The number of background notifications allowed by the system depends on current conditions, but don’t try to send more than two or three per hour.
Silent push notifications will not work when the device is in “Low
Data Mode“.
Slient Push Notification Payload Example.
{
"aps" : {
"content-available" : 1
},
"acme1" : "bar",
"acme2" : 42
}
You have to use "content-available" : 1 in payload for slient push.
On the other hand, if your client running on iOS 12.3 or later Deletions metric
I am working on a project where we are using Firebase Cloud Messaging for push notifications. The following JSON is currently being produced by the backend API and sent to FCM:
{
"priority": "normal",
"delay_while_idle": true,
"dry_run": false,
"time_to_live": 3600,
"notification": {
"body_loc_key": "MyCustomNotificationId"
},
"data": {
// contains notification data
},
"registration_ids": [
]
}
This notification should be silent, meaning it should be only received when the iOS application is in the foreground, however sometimes on some devices this notification also finds its way to the iOS notification tray with the app being in the background as if it had parameters to be displayed there.
I have found out the body_loc_key attribute must be present to iOS devices, otherwise the notification won't ever hit the device, whether the application is in the foreground or background.
The problem occured on the following devices:
Apple iPhone 5,
Apple iPhone 6,
with the possibility of others being affected as well.
Is there a different configuration for the JSON sent to FCM you have used with a success, where the notifications are only being sent to the device when the application is in the foreground?
After fiddling with the FCM payload for sime time we have found out the problem was actually the body_loc_key attribute all along.
In order for a notification to be silent and still sent to an apple device, the payload must meet the following criteria:
priority must be set to normal,
content_available must be set to true,
notification attribute must contain data, but should it contain the body_loc_key attribute it must be set to an empty string - "".
Working payload examples:
// Example one
{
"priority": "normal",
"delay_while_idle": true,
"dry_run": false,
"time_to_live": 3600,
"content_available": true,
"notification": {
"body_loc_key": ""
},
"data": {
// contains notification data
},
"registration_ids": [
]
}
// Example two
// (note that body_loc_key has been replaced with badge)
{
"priority": "normal",
"delay_while_idle": true,
"dry_run": false,
"time_to_live": 3600,
"content_available": true,
"notification": {
"badge": 10
},
"data": {
// contains notification data
},
"registration_ids": [
]
}
Changing the body_loc_key to an empty string pretty much fixed the issue. On top of that we have also found out the following about other attributes of the notification attribute:
badge may be present and is processed, notification remains silent,
title_loc_key has no effect, notification remains silent,
body_loc_args has no effect, notification remains silent.
All three additions apply to scenario where the precedent criteria have been met (empty body_loc_key if/when present, etc.).
The reason why your notification is being sent as display-message and not as silent-message is because you are using the notification payload.
In particular you are using the body_loc_key.
You wrote that you read that body_loc_key is required to send silent-messages.
This is not true.
Can you please link the page where you found this?
Im using the new Firebase platform. Am trying to get a push notification sent by my app server and delivered to my iPhone.
I have the setup working where I manually send the message with the Firebase notifications area on the website, but when I try and send the message with a POST to https://fcm.googleapis.com/fcm/send I get no message being delivered to the device.
I'm sending the following (with auth headers)
{ "notification": {
"title": "Portugal vs. Denmark",
"text": "5 to 1"
},
"to" : "<registration token>"
}
I'm getting a 200 response from the POST with the following body:
{
"multicast_id": 5511974093763495964,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{
"message_id": "0:1463685441784359%3ad254b53ad254b5"
}
]
}
If I try and send to this device directly through the Firebase website it works, but the above form post doesn't. No idea where to go from here!
On iOS the priority field seems mandatory.
{
"to": "cHPpZ_s14EA:APA91bG56znW...",
"priority": "high",
"notification" : {
"body" : "hello!",
"title": "afruz",
"sound": "default"
}
}
If the API returns you a message_id it means that your message has been correctly accepted and it will eventually be delivered to the device.
On Android, messages are delivered as soon as possible (provided that the device is connected of course).
On Apple devices, IF the application is closed or in background, the notification is sent through Apple infrastructure and can be delayed accordingly with Apple documentation.
To reduce the delay of the prioritymessages sent to Apple device you can use the priority parameter.
More details: https://firebase.google.com/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message
I found the message field to be required, as well as the priority field to deliver a message with a POST.
message is not required (and labeled as optional) in the Firebase Console.
I resolved adding the notification tag in request body without priority.
Here is a recap:
I'm trying to send push notifications to my iOS app with GCM. I tried to follow the (Google GCM) and (GCMServerDemo) for my app but I only can receive the notification printed on the xcode output: [body: hello, it's me, sound: default, collapse_key: do_not_collapse, badge: 2, from: 629354528047] but nothing pop out on my testing phone. My server running on python and I have it implemented as:
from gcm import *
gcm= GCM("123...")
DEV_TOKEN = "l0NOTncXJXQ:APA91bGPVHxvF-PCL-PPNic6zhfnpv0aAe5KhvoYOOF_HfLZlCAquMGQb196J5_4zUEzWEirSOWP86d-n4-DJws4nPs5ZXR1c9UOQOPPuuCAjXFz2VIZ-5_SRz8G6D_MzKHv1W7yRrmZ"
reg_ids = [DEV_TOKEN]
notification = {"body": "hello, it's me", "sound": "default", "badge": 2}
response=gcm.json_request(registration_ids=reg_ids, data=notification)
print(response)
My AppDelegate on my app client to detect notification: http://swiftstub.com/621889661/
My ViewController: http://swiftstub.com/89730359
I want my client app receive the notification both when the app is active and when the screen is off (but right now I only can receive the message sent on my server in the xcode output screen, as [body: hello, it's me, sound: default, collapse_key: do_not_collapse, badge: 2, from: 629354528047])
I guess there is a problem when I parse the received message. Can anyone help me to fix it? Thank you.
This is what the gcm payload should look like if all you want to do is display a message to the user:
{
"to":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"body":"This text message will be seen by the user",
"badge": 2,
"sound": "default"
}
}
It will only be visible by default when the app is not in the foreground. When it is, you need to read the message in your AppDelegate's didReceiveRemoteNotification method, and show it to the user yourself.
Edit:
Instead of using gcm.plaintext_request(registration_id=reg_id,data = data)
you might want to try this:
notification = {'body': "hello, it's me", "sound": "default", "badge": 2}
DEV_TOKEN = '**********************************'
reg_ids = [DEV_TOKEN]
response = gcm.json_request(registration_ids=reg_ids, notification=notification)
notification should be outside the data key