GCM HTTP protocol parameters & Azure NotificationHub - ios

We already have GCM/FCM setup up and we are able to send notifications to both iOS and Android devices.
More specifically data-only notifications where we add the parameters ( priority, content_available, collapse_key )
Especially the content_available parameter is crucial when the phone is an iOS device and in order to receive the data-only notifications when the app is in the background. But behaviour seems to be different between https://fcm.googleapis.com/fcm/send call and Portal -> Azure Notification Hub -> Test Send ( or SendFcmNativeNotificationAsync )
Working Case
Everything works as expected when I use the https://fcm.googleapis.com/fcm/send call.
So we have the following message for example:
{
"to": "…REDACTED_THE_ID...",
"collapse_key" : "123456769",
"priority": "high",
"content_available":true,
"time_to_live": 600,
"data": {
"content": {
"id": "9d2b0228-4d0d-4c23-8b49-01a698857710"
},
"dataType": "terminal"
}
}
Issue To Reproduce
But when we use the following message in the Portal -> Azure Notification Hub -> Test Send
Platforms "Android" ( which uses the same Google GCM API Key )
Remove the “to” entry as I am using the "Send To Tag" expression
Azure Notifications hub approves the message and confirms that message was successfully sent.
But then nothing arrives on the iOS smartphone, it seems as if the content_available parameter is not taken into account.
If I add a valid “notification” field (which makes it a NON- data-only notifications ) then it arrives.
{
"collapse_key" : "123456769",
"priority": "high",
"content_available":true,
"time_to_live": 600,
"data": {
"content": {
"id": "9d2b0228-4d0d-4c23-8b49-01a698857710"
},
"dataType": "terminal"
}
}

Related

Getting silent notification values when app starts

I am trying to implement cache meachanism for FCM on IOS. I am using Xamarin Forms with CrossGeeks FirebasePushNotificationPlugin
Push notification service works fine. I am using payload pattern as below
{
"data": {
"message" : "my_custom_value",
"other_key" : true,
"body":"test"
},
"notification": {
"body" : "hello",
"title": "firebase",
"sound": "default",
"content_available" : true
},
"priority": "high",
"condition": "'general' in topics"
}
Above pattern appears delivered notification as alert on IOS main screen.
I have written a Dependency Service for getting undeleted or unopened accumulated notifications when app starts. Dependency Service include below codes
await UNUserNotificationCenter.Current.GetDeliveredNotificationsAsync();
When I use above payload, I can get accumulated notifications. But when I use payload pattern as below, I can not.
{
"data": {
"message" : "my_custom_value",
"other_key" : true,
"body":"test"
},
"notification": {
"content_available" : true
},
"priority": "high",
"condition": "'general' in topics"
}
Actually I would like to send 2 payload types for every notification for my cache mechanism because of prevent the user's delete action. After that, I would like to show cached notifications without any lost in my app's notification page.
Shortly my question about "I am not getting silent payload values from UNUserNotificationCenter this approach is possible or not?"
Or can I prevent the user's notification delete action from IOS main screen when my app is terminated.
Note: My minimum OS version is 10.0 in info.plist
Thank you in advance.

iOS Push notifications using cordova. The notification is never received

I created a sample Cordova app which is using "phonegap-push-plugin".
That app doesn't have any complexity. On "deviceready" I run the plugin initialization code as shown here:
var push = PushNotification.init({android: {}, ios: {
sound: true,
alert: true,
badge: true,
categories: {
invite: {
yes: {
callback: 'accept',
title: 'Accept',
foreground: true,
destructive: false
},
no: {
callback: 'reject',
title: 'Reject',
foreground: true,
destructive: false
},
maybe: {
callback: 'maybe',
title: 'Maybe',
foreground: true,
destructive: false
}
},
delete: {
yes: {
callback: 'doDelete',
title: 'Delete',
foreground: true,
destructive: true
},
no: {
callback: 'cancel',
title: 'Cancel',
foreground: true,
destructive: false
}
}
}
}})
push.on('notification', data => {
console.log(data.message);
console.log(data.title);
console.log(data.count);
console.log(data.sound);
console.log(data.image);
console.log(data.additionalData);
})
push.on('emailGuests', data => {
console.log('I should email my guests');
});
push.on('snooze', data => {
console.log('Remind me later');
});
push.on('registration', data => {
console.log(data.registrationId);
console.log(data.registrationType);
});
push.subscribe('xx', console.log)
And this is the log output to console:
=> Successfully subscribe to topic xx
// The first run (after app install) will ask for permissions. If I click allow the lines below are printed to console.
=> dCAtjhCFBcU:APA91bG90c8VhNl_BzZ-2e9fmq_9fN6jfrRNJ1LPCRIpKnZ-AG-eLY4xtX84oJRZBh2D....KtNNQ35GM8ubPF5zr8HqeB6jffs
=> FCM
In order to push I'm sending the following payload to the Legacy Server https://fcm.googleapis.com/fcm/send.
{
"priority": "high",
"to": "/topics/xx", // I tried this but I also tried to specify the device token received upon "registration" event. I did this using to:<device_token> and also using registration_ids: [<device_token>].
"notification": {
"title": "My Message",
"body": "My Message Body",
"badge": 1,
"content-available": "1", // I tried with and without
"category": "identifier", // I tried with and without
"thread-id": "id", // I tried with and without
"sound": "default",
"icon": "default"
},
"data": {
"title": "A short string describing the purpose of the notification",
"body": "The text of the alert message",
"clubId": 1000
},
"notId": 1,
"custom_key1": "value1",
"custom_key2": "value2"
}
Note: I tried every combination possible in what concerns the app state: App in background; app closed; app in foreground; The event "notification" has never fired and the push notification was never received.
The request sent to the FCM server returns a message id when I use the topic (which is understandable since other devices subscribe the topic). For that reason my android that has subscribed to the same topic receives the message. The iOS in the other hand receives nothing!
{
"message_id": 5059997308576486332
}
If I try to specify the token that I received upon registration, I will get a slightly different message. Most of the time the token received upon registration works and the results will contain a string id. But this is temporary since a few minutes later the token become "NotRegistered".
{
"multicast_id": 88880398234xxxxx7,
"success": 0,
"failure": 1,
"canonical_ids": 0,
"results": [
{
"error": "NotRegistered" // <-- This happens after a few minutes. I have to delete the app and reinstall it in order to get a new token.
}
]
}
This is the build configuration
Notifications are correctly enabled on my iOS device. What am I missing?
Updated:
Accessing Apple's APN directly (yup... no FCM!)
I would like to send my push notifications through FCM but in order to determine the cause of the issues described above, I decided to try APN directly. To do this, I had to remove the from the app's config.xml, so phonegap-push-plugin can obtain a token from APN and not from FCM.
Now, using the new token and a server that uses node-apn module to communicate with APN server, I'm able to send push notifications to my iOS app. The downside of this, is that I lose the ability to push to topics since this is a FCM only feature.
The only thing that I still don't know is how to use the topic to target devices in the APN network, that are subscribed by the push.subscribe() method.
Checkout my issue here.
Any help on this too?
So, turns out there's an issue with the push plugin.
This issue only impacts users on iOS device apps that use the FCM.
If you use the APNs it works.
You can check my answer in here: https://github.com/phonegap/phonegap-plugin-push/issues/2644#issuecomment-445346335
And my initial issue reporting in here:
https://github.com/phonegap/phonegap-plugin-push/issues/2613

Firebase cloud messaging for iOS: don't receive notifications from POST request (only from composer tool)

I setup Firebase cloud messaging for iOS using their quick start tutorial and API docs: https://firebase.google.com/docs/cloud-messaging/ios/first-message
I sent message to my iPhone from Firebase composer tool and it was successful. But the next step I need is to receive a notification sent with regular POST request. I found that it's possible to do with legacy protocols: https://firebase.google.com/docs/cloud-messaging/auth-server#authorize_legacy_protocol_send_requests
I tried to send the following:
{ "data": {
"message": "This is a Firebase Cloud Messaging Topic Message!"
},
"to" : "myIphoneTokenHere"
}
via postman with authorization key for my Firebase project and received success in response:
{
"multicast_id": 5644065455367933439,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{
"message_id": "0:1513338642327024%5529b926f9fd7ecd"
}
]
}
But I there was no notification on my iPhone unlike with the composer tool.
Wondering what can I try to solve this problem, how can I debug what goes wrong?
Solved the issue by changing request body to:
{
"content_available": true,
"notification" : {
"body" : "This is a Firebase Cloud Messaging Topic Message!",
"title" : "FCM Message"}, "to" : "myIphoneTokenHere" }

Notification from FCM is sometimes displayed in iOS notification tray

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?

Can't send push notifications using the server API

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:

Resources