Firebase: FCM: payload syntax for Android/iOS collapsable and non-collapsable notifications - firebase-cloud-messaging

I am struggling to find the correct syntax and specific payload keys to achieve collapsable and non-collapsable notifications on iOS, and non-callapsable notifications on Android. I've got collapsable working on Android, so I know I'm moving in the right direction.
I am using the admin.messaging().send(payload) function in my Node.js Cloud Functions file.
My collapsable payload example:
{
notification: {
title: `${userName}`,
body: `${message.msg}`
},
data: {
click_action: "FLUTTER_NOTIFICATION_CLICK",
v_type: 'chatMsg',
v_uid: uid,
v_cid: cid,
},
android: {
collapse_key: cid,
},
apns: {
headers: {
'apns-collapse-id': cid,
}
},
token: tokenDoc.data().notificationToken,
}
For non collapsable messages I use the 'apns-id' key instead of 'apns-collapse-id'. I'm not sure what the equivalent is for android. The documentation on Firebase covers these keys, but there is no example of how the payload structure should look.
Firebase documentation states that messages are non collapsable by default, but how does the device know when to replace an existing notification related to the same information? I assume I have to set an id for the device to know to overwrite an existing notification.

Related

Message format for deeplink with react-native-push-notification

I am using react-native-push-notification library to send local notifications from my ios app. I have setup deeplink using react navigation. I have also managed the local push notification to deeplink into specific app screen on click. But this requires me to set the in the message property. This means the resulting lo shows the URL in its display. This is ugly and I would like to hide the URL. Any pointers?
Here is how i schedule local notification
PushNotification.localNotificationSchedule({
title: "main title",
subtitle: "fake sub title",
message: "example://detail/one",
bigText: "My big text that will be shown when expanded",
date: new Date(Date.now() + 10 * 1000),
allowWhileIdle: false,
});
Here is my onNotification code
onNotification: function (notification) {
console.log("NOTIFICATION:", notification);
let isClicked = notification.data.userInteraction === 1
if (isClicked) {
Linking.openURL(notification.message)
}
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
Now this results in the example://detail/one url being displayed in notification. How do i achieve this?
Not exactly a solution to the above issue. But I switched to Notifee for local push notifications. And it just worked! So much easier to install and very minimal configuration needed. Was just an intuitive I expected the notification library to be.

Duplicate fcm push notification in react native android backgroundhandler

I developed react native application with rnfirebase and notifee for sending the push notification. foreground is working properly, message is displayed only once. but the background notification is displaying twice like one is from messaging().setBackgroundMessageHandler and another one is android's default push notification. First message is from default push notification and next one is from firebase messaging. So how do I remove android's default push notification. I'm also checked that first default notification is not using the firebase messaging and notifee. It's comes from outside of react native like android's native push notification
The notifications that you are seeing are most likely one from firebase and another from Notifee.
In my project I was handling the notifications that were coming from firebase via firebase.messaging().onMessage and inside this listener I was showing a local notification using Notifee so that the notification shows in the foreground.
async showNotificationInForeground(message: FirebaseMessagingTypes.RemoteMessage) {
const { messageId, notification, data } = message
const channelId = await Notifee.createChannel({
id: messageId,
name: 'Pressable Channel',
importance: AndroidImportance.HIGH,
})
await Notifee.displayNotification({
title: notification?.title || '',
body: notification?.body || '',
data,
android: {
channelId,
importance: AndroidImportance.HIGH,
pressAction: {
id: messageId,
},
smallIcon: 'ic_stat_name',
localOnly: true,
},
})
}
However what was happening was that I was calling this showNotificationInForeground method to show the local Notifee notification on both firebase's background and messaging listeners ie: firebase.messaging().onMessage and firebase.messaging().setBackgroundMessageHandler
So what I ended up doing was only calling the showNotificationInForeground method in onMessage listener and not in setBackgroundMessageHandler, which resulted in showing the local notification in the foreground, and the firebase notification in the background.
If this is not the case for you, you are most likely registering an extra notification receiver inside your AndroidManifest.xml file which is causing the duplication
I had the same problem, where there were two notifications a) 1 from notifee (which I wanted to keep) b) from FCM (which I didnt want).
Sending a data only message from my custom server solved the issue. Below is a snippet of the serverside for sending data only message :
const admin = require("firebase-admin");
// Do other stuff like create an express server to listen and trigger sending message
// Note dont forget to to initialize the app
await admin.messaging().sendToDevice(
tokens, // ['token_1', 'token_2', ...]
{
data: {
owner: "Me",
user: "My Friend",
},
},
{
// Required for background/quit data-only messages on iOS
contentAvailable: true,
// Required for background/quit data-only messages on Android
priority: "high",
}
);
You can use other methods as well, just make sure that FCM doesnt include notification and is data only.

How to set the remote notification sound for iOS in react native app?

Im using react-native-firebase and firebase cloud messaging for remote notifications (v5.6.0), and I have my firebase cloud function's notification payload set. Im trying to set the notification sound for iOS/android. what I have currently is:
exports.sendChatNotification = functions.firestore.document('messages/{document}').onCreate((event) => {
const writeData = event.data();
const { receiverToken, senderName, content } = writeData;
const payload = {
notification: {
title: 'Chat Message',
body: senderName + ' has sent you a message',
sound: 'Complete'
}
};
return admin.messaging().sendToDevice(receiverToken, payload).then((msgDevicesResponse) => {
console.log(JSON.stringify(msgDevicesResponse));
});
});
Currently experiencing this notification sound playing the default for iOS, and am unable to per-select an existing iOS tone, such as "Complete". I understand from reading firebase docs that the 'sound' property of the notification payload only works for the android platform.
Since im using react-native-firebase, I looked at their documentation for Cloud Messaging, and found this Notification object that has iOS and android properties: https://rnfirebase.io/reference/messaging/notification
both platform properties have a sub-property sound, but Im unsure of how to integrate this, considering my notifications are being set in a firebase cloud function, which uses firebase.admin
My goal is to set the iOS notification sound from the os's list of tones. How can this be done?

Display custom FCM push notification in React Native iOS

I am working on a react native project which wants to receive the FCM push notification. And I am using the react-native-fcm module. What I want to do is to show the notification manually.
In this module, there is a function
import {Platform} from 'react-native';
import FCM, {FCMEvent, RemoteNotificationResult, WillPresentNotificationResult, NotificationType} from 'react-native-fcm';
FCM.on(FCMEvent.Notification, async (notif) => {
console.log(notif);
});
where the 'notif' should be the message that was received by the device. However, I cannot receive the console.log(notif); is never called when the notification was sent to the device.
What I want to do is to use the following function to show the notification by handling the notif json manually.
FCM.presentLocalNotification({
id: "UNIQ_ID_STRING", // (optional for instant notification)
title: "My Notification Title", // as FCM payload
body: "My Notification Message", // as FCM payload (required)
sound: "default", // as FCM payload
priority: "high", // as FCM payload
click_action: "ACTION", // as FCM payload
badge: 10, // as FCM payload IOS only, set 0 to clear badges
number: 10, // Android only
ticker: "My Notification Ticker", // Android only
auto_cancel: true, // Android only (default true)
large_icon: "ic_launcher", // Android only
icon: "ic_launcher", // as FCM payload, you can relace this with custom icon you put in mipmap
});
I also realize that the message sent for FCM also would affect how the module to show the message. For more details, check FCM.
I guess my FCM setup should be correct as I can receive the notification. My react-native app can receive the notification if I send the message with key "notification". Like:
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
But the console.log(notif); in the previous function still haven't been called.
I also tried to send the notification with payload
"data" : {
"title" : "Mario",
"body" : "PortugalVSDenmark"
}
But the console.log(notif); is still not been called.
Does anyone know about the mechanism how react-native-fcm and firebase-cloud-messaging work?
Thank you so much!
Please use below code to get FCM token, which should be registered with firebase. After successful registration, You will receive the remote notifications in "notif".
FCM.on(FCMEvent.RefreshToken, (token) => {
console.log("registration token:" + token);
// fcm token may not be available on first load, catch it here
});

React-native FCM: Can't access notification data when the app is in background or killed

Im am trying to make work react-native-fcm, with firebase cloud messaging and a react-native app.
I am focusing mainly in Android
react-native#0.48.0
react-native-fcm#10.0.2
OS: Android - Emulator - 7.0.2
When my app is in foreground, its working perfectly, I receive the data in this function
FCM.on(FCMEvent.Notification, async (notif) => {
And I can handle everything
But when the app is in background, the notification is received, but when I tap the banner, the app goes foreground, the same function is triggered, but the notif object is different, and don't contains my data.
When the app is killed, also the notification is received, but when I tap the banner, the app starts, the
FCM.getInitialNotification()
is triggered, and my notif object doen't also contain the data, the same behaviour than in background
I am testing the format of the messages using node-gcm library, of firebase web interface, but nothing works.
This is a sample of my message, but I have tryed tons of combinations:
let message = new gcm.Message({
priority: 'high',
content_available: true,
timeToLive: 3,
data: {
key1: 'message1',
key2: 'message2'
},
notification: {
title: "Hello, World",
icon: "ic_launcher",
body: "This is a notification that will be displayed if your app is in the background."
},
custom_notification: {
key1: 'message1',
key2: 'message2'
}
});
How should I proceed to send and receive data in those cases? Because is driving me crazy.
If you need more data, ask for it :)
Thanks!!
in my case, i was missing the notification's data setup when building the notification on foreground notification event firebase.notifications().onNotification
new firebase.notifications.Notification()
.setNotificationId(fcmNotification.data.notificacionId)
.setTitle(fcmNotification.title)
.setBody(fcmNotification.body)
.setData(fcmNotification.data) // <- this little bastard
so, when tapping the notification data was undefined on firebase.notifications().onNotificationOpened even when the json that comes in firebase.notifications().onNotification had data field filled