Expo - Implementing Notifications Set App Icon Badge Number - ios

Despite numerous attempts to implement the app icon badge number in our Expo app, the app icon badge number could not be set. The documentation on setting notifications app icon badge number is also very limited. We are trying to set app icon badge number to 1 when there is new push notification and then reset the app icon badge number to 0 after the user clicked on the notification.
Can anyone point out what’s wrong here?
The following is the callback function for the Notifications listener.
handleNotification = async (notification) => {
const { origin, data, notificationId } = notification
const notif = { id: notificationId, ...data }
// set notifications badge count
try {
const setAppBadgeCount = await Notifications.setBadgeNumberAsync(1)
console.log(`showing app badge number to 1 ${setAppBadgeCount}`)
} catch (err) {
console.log('did not manage to show notif app badge count!', err)
}
if (origin === 'selected') {
this.navigateToNotificationScreen(data)
try {
const resetAppBadgeCount = await Notifications.setBadgeNumberAsync(0)
console.log(`reset app badge count ${resetAppBadgeCount}`)
} catch (err) {
console.log('did not manage to reset notif app badge count!', err)
}
} else { // origin === 'received', show in-app
const { dispatch } = this.props
dispatch(setActiveNotifications([notif]))
setTimeout(() => {
dispatch(setInactiveNotifications([notif]))
}, 10000)
}
}
Thanks in advance!

Ah I got reminded that I didn't leave my solution here. In my case, the Expo front end code was written perfectly. The way I wrote it above works like a charm. Issue for me is that the backend request sent to the Expo server wasn't written correctly. Refer to this link - https://docs.expo.io/versions/latest/guides/push-notifications/#sending-notifications-from-your-server
[
{
"to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
"sound": "default",
"body": "Hello world!"
},
{
"to": "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]",
"badge": 1,
"body": "You've got mail"
},
{
"to": [
"ExponentPushToken[zzzzzzzzzzzzzzzzzzzzzz]",
"ExponentPushToken[aaaaaaaaaaaaaaaaaaaaaa]"
],
"body": "Breaking news!"
}
]
Specifically, I didnt add the param "badge": 1 in the request body of the notification sent to the Expo server. As a result, the app icon badge number is not set at all.

Related

Cannot receive FCM (Push Notification iOS)

I make app by React Native.
Few days ago,I was able to receive FCM. But now I cannot.
Client app permissions notification, I set Xcode(capability),firebase and Apple Developer(APNs setting).
And console.log tells me success.
But I cannot receive notification. Although few days ago I could.
Is this error in firebase??
I don't know cause, please help me m(_ _)m
=======environment==========
Xcode Version 11.3
"react-native-firebase": "^5.6.0"
"react-native": "0.61.5"
"firebase-admin": "^8.9.0"
=======addition========
Regenerating APNs and setting, I could receive notification.
But next day, I couldn't receive notification.
APNs is valid in only one day???
Most probably, in your Firebase console number of potential users are eligible for this campaign is 0 currently.
"Estimate based on approximately 0 users who are registered to receive notifications. Some targeted users will not see the message due to device inactivity. For recurring campaigns, estimate is for initial send only."
Possible solution:
1) If that's the case (0 users are registered)
--> Check if the fcmToken is received.
getFcmToken = async () => {
const fcmToken = await firebase.messaging().getToken();
if (fcmToken) {
console.log(fcmToken);
this.showAlert(‘Your Firebase Token is:’, fcmToken);
} else {
this.showAlert(‘Failed’, ‘No token received’);
}
}
2) If the number is not zero
--> Most probably your app is opened in foreground and the notification is not displayed.
--> Try to lock your iPhone screen and the notification will appear, else try to handle it which the app is in foreground
messageListener = async () => {
this.notificationListener = firebase.notifications().onNotification((notification) => {
const { title, body } = notification;
this.showAlert(title, body);
});
this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
const { title, body } = notificationOpen.notification;
this.showAlert(title, body);
});
const notificationOpen = await firebase.notifications().getInitialNotification();
if (notificationOpen) {
const { title, body } = notificationOpen.notification;
this.showAlert(title, body);
}
this.messageListener = firebase.messaging().onMessage((message) => {
console.log(JSON.stringify(message));
});
}
3) Check if the cert has expired (unlikely) since you mentioned that it's still working a few days back.

is there any way to send different badge count to different users in a same topic?

I have FCM integration in my Node.js project where I am sending number of notifications to the IOS users and I need to manage notification count i.e. Badge count which will be different across the devices but I am sending notification to a particular topic to which these devices are subscribed.
my Payload is :
var payload = {
notification: {
title: "Title...",
body: "Notification Body...",
sound: "customeSound.caf",
badge : "?"
},
data: {
testData: "custom data"
}
},
topic = "topicName";
admin.messaging().sendToTopic(topic, payload)
.then(function (response) {
// See the MessagingTopicResponse reference documentation for the
// contents of response.
console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
});
All devices that are subscribed to the corresponding topic will receive the same payload you set.
You'll have to send a separate payload for each device. Or if applicable, maybe just group the ones with the similar badge value -- but that would require you to send to a group of tokens (using registration_ids) instead of sending to a topic.
If you have the devices tokens and you want to send the badge counts to respective device token,
Instead of sending them one by one ( Which I personally think is not a good idea) the best alternative you can do is:-
You can achieve this by doing something like.....
First of all you need to query your DB to get the device token and badge count respectively
So say like you have and array
const badgeCounts = [{
device_token:'aaaaaaaaaaaaaaaaaaaaaa',
badge_count: 1
},{
device_token:'bbbbbbbbbbbbbbbbbbbbbb',
badge_count: 2
},{
device_token:'cccccccccccccccccccccc',
badge_count: 3
},{
device_token:'dddddddddddddddddddddd',
badge_count: 4
}]
Now you can map over this array and compose array of fcm messages, something like below :-
const fcmMessages = [];
badgeCounts.forEach((data) => {
fcmMessages.push({
token: data.device_token, //device token
apns: {
payload: {
aps: {
alert: {
title: "your title",
body: "your body",
},
badge: data.badge_count, // badge
contentAvailable: true,
},
},
},
data: {
// any payload goes here...
},
notification: {
title: "your title",
body: "your body",
},
});
});
/// in firebase messiging you can do like
messaging.sendAll(fcmMessages);
refer doc https://firebase.google.com/docs/reference/admin/node/admin.messaging.Messaging-1#sendall

Firebase-admin doesn't send iOS APN notification

I can send push notifications from Firebase Console Notifications to my iOS device, and it works perfectly being the app in foreground and background.
When I try to send them using Firebase-admin by NodeJS it only works when the app is in foreground, in background nothing happens.
I think that the communications between FCM-APNs are good because it works with the console.
This is my NodeJS code:
function sendFCM(registration_ids, data, collapseKey) {
const options = {
priority: "high",
collapseKey : collapseKey,
contentAvailable : true,
timeToLive: 60 * 60 * 24
};
const payload = {
data: data,
notification: {
title: "My title",
text: "My description",
sound : "default"
}
}
admin.messaging().sendToDevice(registration_ids, payload, options)
.then(function(response) {
console.log("Successfully sent message:", response);
})
.catch(function(error) {
console.log("Error sending message:", error);
});
}
What do you think that it's happening? Do you know some way to log the issue?
The Server Protocol documentation indicates the key for notification text is body, not text. See if this change makes a difference:
const payload = {
data: data,
notification: {
title: "My title",
body: "My description", // <= CHANGE
sound : "default"
}
}

Firebase Cloud Messaging not sending aps payload in correct format for iOS Notification Content & Service Extensions

I'm trying to implement notifications using Firebase. The notification is received correctly when the app is in the background or foreground. So, the basic mechanics are working.
Now I've added Content Extensions and Service Extensions to the app. The Content Extension works when I use a local notification, but the Firebase message payload seems incorrect as far as the optional fields are considered. Here is a link to an image of my console:
And here is the Firebase remote notification payload that comes across (with some of the long Google numbers edited for anonymity:
{
aps =
{
alert =
{
body = "Eureka! 11";
title = "Patient is not doing well";
};
};
category = provider-body-panel;
gcm.message_id = 0:149073;
gcm.n.e = 1;
google.c.a.c_id = 2825604;
google.c.a.e = 1;
google.c.a.ts = 149073;
google.c.a.udt = 0;
mutable-content = 1;
}
It appears that the "category" and "mutable-content" are not in the correct place. They should be in the aps payload.
How can I get those options to be in the payload so that my app can correctly parse it and connect it with the Content and Service Extensions?
To start off, I'm going to mention that there are two types of message payloads for FCM. notification and data. See the documentation here
When sending notifications through the Firebase Notifications Console, it will be treated as a notification payload. However, if you add in Custom Data, it will add it in the payload as a custom key-value pair.
For example, in your post, the FCM payload should look something like this:
{
"notification": {
"body" : "Eureka!",
"title": "Patient is not doing well"
},
"data": {
"category": "provider-body-panel",
"mutable-content" : true,
"click_action" : "provider-body-panel"
}
}
What's wrong?
click_action should be inside notification.
mutable-content should be mutable_content (notice the underscore) and should be on the same level as notification.
(this one I might've misunderstood, but) There is no category parameter for FCM, click_action already corresponds to it.
See the docs for the parameters here.
It it is currently not possible to set the value for click_action and mutable_content when using the Firebase Notifications Console. You'll have to build the payload yourself, something like this:
{
"to": "<REGISTRATION_TOKEN_HERE>",
"mutable_content" : true,
"notification": {
"body" : "Eureka!",
"title": "Patient is not doing well",
"click_action" : "provider-body-panel"
}
}
Then send it from your own App Server. You could also do this by using Postman or cURL
"mutable-content should be "mutable_content" (keyword for firebase server to send as mutable-content for IOS) as you mentioned in your post, I think you left out in edit.
Below is an example with also the corrected format for the data section in the json sent to the FCM server.
So update would be:
{
"to" : "YOUR firebase messaging registration id here",
"mutable_content":true,
"notification": {
"title": "Its about time",
"body": "To go online Amigo",
"click_action": "NotificationCategoryIdentifier ForYourNotificationActions"
},
"data":{
"customKey":"custom data you want to appear in the message payload"
"media-attachment":"mycustom image url",
"catalogID":"mycustom catalog for my custom app"
}
}
Update Firebase Admin SDK and use sendMulticast(payload) method
var admin = require("firebase-admin")
admin.initializeApp({
credential: admin.credential.applicationDefault(),
});
// Create a list containing up to 500 registration tokens.
// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
'YOUR_REGISTRATION_TOKEN_1',
// …
'YOUR_REGISTRATION_TOKEN_N',
];
// See documentation on defining a message payload.
var message = {
notification: {
title: '$FooCorp up 1.43% on the day',
body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
},
tokens: registrationTokens,
apns: {
payload: {
aps: {
'mutable-content': true, // use single quote
'category': 'INVITE_CATEGORY' // use single quote
}
},
},
};
// Send a message to the device corresponding to the provided
// registration tokens.
admin.messaging().sendMulticast(message)
.then((response) => {
if (response.failureCount > 0) {
const failedTokens = [];
response.responses.forEach((resp, idx) => {
if (!resp.success) {
failedTokens.push(registrationTokens[idx]);
}
});
console.log('List of tokens that caused failures: ' + failedTokens);
}
});
Ref: https://firebase.google.com/docs/cloud-messaging/send-message#send_messages_to_specific_devices
This worked for me with Cloud functions with Node.js
const payload = {
notification: {
title: name,
body: messageText,
badge: "1",
mutable_content: "true"
},
data: {
type: "MESSAGE",
fromUserId: name,
attachmentUrl: imageUrl
}};

Not receiving back a delivery_receipt_notification from GCM CCS

I'm trying to get a receipt from CCS, but I'm just not able to.
Here is what I'm doing:
I have a go script:
package main
import (
"fmt"
"github.com/brunohenrique/go-gcm/ccs"
)
var (
user = struct {
gcmToken string
}{"mg0xe56LfjE:APA91bFHtHVQt85iNgyzTeDowovIGPAD_NbBjURppy1LgV9_oaM2R_9zn1fDXNuEeOoALTj7F8e8JmNPI3Md-CbbgTxdvxVrONFVfGz2dOujsaGkZjEhJcBH8sWvRNYZNIp2j2QliAEX"}
)
func main() {
con := connect()
// Sends a message
con.Send(&ccs.OutMsg{
To: user.gcmToken,
ID: "m-1366082849205",
Notification: map[string]interface{}{
"title": "Hey!",
"body": "There",
"sound": "default",
},
TimeToLive: 600,
DeliveryReceiptRequested: true,
DelayWhileIdle: true,
})
// Listen to messages
for {
m, err := con.Receive()
if err != nil {
fmt.Printf(">>> Err: %+v \n", err)
}
go func(m *ccs.InMsg) {
fmt.Printf(">>> InMsg: %+v \n", m)
}(m)
}
}
Everything seems alright when I run the script, but no receipt message back:
And this is what I'm doing when I get the notification:
Am I doing something wrong or missing something?
Thanks for trying out GCM on iOS.
Unfortunately, delivery receipts are not available for display notifications on iOS at the moment.
Not sure if you're trying this on Android or iOS, since it works for me on Android but it doesn't always work on iOS.
Delivery receipts for iOS do not work with the notification parameter in the request. I was able to get it to work for a plain data message i.e. with payload
{
"to" : <reg id>,
"data" : {
"hello" : "world",
"id" : 123
}
}
But if I added the notification payload to the above one it didn't work.
I would assume that since a notification payload message needs to be sent via APNS there is no way for them to know whether the message was delivered or not since APNS does not return any result.
For a no notification message since it's received only when the app is in the foreground they would be able to verify if the message was delivered or not.

Resources