React Native: Disable sound/vibration on push notification - firebase

I'm sending push notifications from server to clients via google FCM.
In the react-native app I've registered these listeners:
this.notificationOpenedListener = firebase.notifications().onNotificationOpened(async (notificationOpen) => {
})
this.notificationListener = firebase.notifications().onNotification(async (notification) => {
});
the notification data contains information if there should be a sound / vibration or not when the notification is received.
However, I can't find any documentation about completely disabling sound/vibration on demand.
How can I achieve this?
UPDATE
I've tried setting sound to an empty string on server side, but there's still sound/vibration on notification.
var message = {
data: {
userId: fromUserId,
},
notification: {
title: `My notifcation`,
body: `Body`,
sound: "",
},
}
return sendToTopic(topicId, message)

When setting your notification target, remove sound parameter.
const notify = {
...message.notification,
show_in_foreground: true,
notify_type: message.NotificationType,
obj_id: message.ObjectId,
sound: '' // remove this
};
firebase.messaging().createLocalNotification(notify);

I'm not sure how you are setting up your Push notifications but you can tag extra data into the JSON like this:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
}
}
This means you could add a boolean to it to manually play a tone on arrival or not play a tone when the subscription fires, like this:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark",
"playTone" : "true"
}
}
}
Then it's the case of having a check in your callback to check the response:
this.notificationListener = firebase.notifications().onNotification(async (notification) => {
if(notification.data.playtone) {
// Play Tone
} else {
// Don't
}
});
In general though push notifications are handled by the OS and not the application, you can hook into it like you have and perform actions on the arrival of a push notification but normally they all arrive in the same "Drop everything and deal with me" style.
Both Android and Apple do support priority but it might not be what you're after:
https://firebase.google.com/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message

Related

Flutter - Background notifications not working in iOS

I'm creating a public chat app in Flutter, and I can't receive background notifications on iOS, when I trigger the method admin.messaging().send(payload) from my Cloud Function.
Here's my payload in the Cloud Function :
var payload = {
notification: {
title: `My Title`,
body: `My message`,
},
android: { priority: "high" },
apns: {
payload: {
aps: {
contentAvailable: true,
},
},
headers: {
"apns-push-type": "background",
"apns-priority": "10",
"apns-topic": "io.flutter.plugins.firebase.messaging", // bundle identifier
},
},
topic: `mytopic`,
};
I tried a bunch of different payloads :
I tried notification + data
I tried only data (no notification) (in that case, I have to locally display the notification, but it is not working because the function FirebaseMessaging.onBackgroundMessage is never called)
I tried to change "apns-priority" to 5
I tried using a token instead of a topic
I set up carefully all I need to configure, thanks to the official documentation :
https://firebase.flutter.dev/docs/messaging/usage/
I also checked Github issues, like these ones :
1041, 6112, 5988, 1644, 4300, 4097
What is working :
Background and foreground notifications on Android and iOS, when sent from Firebase Console (in 'Cloud Messaging' section)
Background and foreground notifications on Android only, when sent from Cloud Function
Foreground notifications on iOS, when sent from Cloud Function
What is NOT working :
Background notifications on iOS when sent from Cloud Function
When app is terminated, it does not work as well.
I finally resolved this issue ! 🎉
I simply removed the line "apns-push-type": "background" in my payload.
Now it is working.
It appears that the line "apns-topic" was useless as well.
Here is my final payload :
var payload = {
notification: {
title: `# ${context.params.passion}`,
body: `${newMsg["senderPseudo"]} ${
type == "image" ? "a envoyé une image." : `: ${newMsg["message"]}`
}`,
},
// Set Android priority to "high"
android: {
priority: "high",
},
// Add APNS (Apple) config
apns: {
payload: {
aps: {
contentAvailable: true,
},
},
headers: {
//"apns-push-type": "background", // This line prevents background notifications to be displayed
"apns-priority": "10",
},
},
token: "dnqTQVso60GfnnuOjHv8_e:APA91bElr-K3xkQMdYHX8VMrMZNCYCjO4zJlGseRh25AS_GT7cg9zlOGdQl4KXvr88ypeWjZjrPzrLRHitsQ-JKQK057ZQb_36c_lfsNjHXbYMYI2iS3jV_HGWf7Ene-ZlPvOb0aRr8u"
};

React Native Firebase onNotificationOpened not able to access data payload

Using Google Firebase notification in React Native I am not able to access data payload onNotificationOpened.
Below is the example.
this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
const { title, body } = notificationOpen.notification;
console.log(JSON.stringify(notificationOpen.data)) // {}
});
notificationOpen.notification.data is undefined.
I am triggering the API in the following format.
{
"to": <dev_token>,
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
},
"data" : {
"Nick" : "Mario",
"Room" : "PortugalVSDenmark"
}
}
using react-native-firebase : "5.5.6"
Thanks in advance.

HMS cancel notification with tag not working ( (HMS push kit)

I am integrating Huawei Push Kit (https://pub.dev/packages/huawei_push) in Flutter application.
I test to schedule a notification to notify every minutes in my Huawei phone, and I able to get the notification as expected. But when I tried to cancel the notification with clearNotification() function (shown below), the notification seem like not cancelled. Wondering do I miss out anything?
scheduleLocalNotification() async {
try {
Map<String, dynamic> localNotification = {
HMSLocalNotificationAttr.TITLE: 'Notification Title',
HMSLocalNotificationAttr.MESSAGE: 'Notification Message',
HMSLocalNotificationAttr.TICKER: "OptionalTicker",
HMSLocalNotificationAttr.TAG: "push-tag",
HMSLocalNotificationAttr.BIG_TEXT: 'This is a bigText',
HMSLocalNotificationAttr.SUB_TEXT: 'This is a subText',
HMSLocalNotificationAttr.LARGE_ICON: 'ic_launcher',
HMSLocalNotificationAttr.SMALL_ICON: 'ic_notification',
HMSLocalNotificationAttr.COLOR: "white",
HMSLocalNotificationAttr.VIBRATE: true,
HMSLocalNotificationAttr.VIBRATE_DURATION: 1000.0,
HMSLocalNotificationAttr.ONGOING: false,
HMSLocalNotificationAttr.DONT_NOTIFY_IN_FOREGROUND: false,
HMSLocalNotificationAttr.AUTO_CANCEL: false,
HMSLocalNotificationAttr.INVOKE_APP: false,
HMSLocalNotificationAttr.ACTIONS: ["Yes", "No"],
HMSLocalNotificationAttr.REPEAT_TYPE: RepeatType.MINUTE,
HMSLocalNotificationAttr.FIRE_DATE:
DateTime.now().add(Duration(minutes: 1)).millisecondsSinceEpoch,
};
Map<String, dynamic> response =
await Push.localNotificationSchedule(localNotification);
print("Scheduled a local notification: " + response.toString());
} catch (e) {
print("Error: " + e.toString());
}
}
clearNotification() async {
Push.cancelNotificationsWithTag('push-tag');
}
Currently, Huawei Push Kit does not support clearNotification() function. You can use the Sending Downlink Messages API. There is an auto_clear parameter, and you can set message display duration, in milliseconds. Messages are automatically deleted after the duration expires.
Please refer to the following code:
{
"validate_only": false,
"message": {
"android": {
"notification":{"body":"Big Boom Body!","click_action":{"type":3},"title":"Big Boom Title","auto_clear": 360000}
},
"token":[
"token1",
"token2"]
}
}
For more information, see docs
Your clearNotification function which calls Push.cancelNotificationWithTag('push-tag') is async.
Possibility is Push.cancelNotificationWithTag might get called before.
Either call it directly and not thru async function or add await.

this.fcm.onNotification().subscribe() not called on Android device

I have an Ionic 4 app which I have integrated with Firebase for authentication etc. I want to implement Firebase's cloud messaging so I can push messages to my app on both Android and iOS. I have done this pretty easily on iOS and I have sent a message via Postman which shows on my iPhone and I see the JSON of the message I have sent. When I try it on Android it doesn't work. Both devices receive the message but handle it very diferently.
I have read in a lot of places that you need to set the click_action to FCM_PLUGIN_ACTIVITY but when I do that the app doesn't even open on Android. When I take it out the app loads when you click the message but it doesn't show the body of the message like on iOS in my alert.
import { FCM } from '#ionic-native/fcm/ngx';
...
constructor(public platform: Platform, public fcm: FCM)
...
this.platform.ready().then(() => {
this.fcm.onNotification().subscribe(data => {
alert(JSON.stringify(data));
});
this.fcm.onTokenRefresh().subscribe(token => {
// Register your new token in your back-end if you want
// backend.registerToken(token);
});
}).catch((error) => {
this.showFailureMessage(error.message);
});
This is what I am posting off to... https://fcm.googleapis.com/fcm/send
{
"notification":{
"title":"My Title",
"body":"My Body",
"sound":"default",
"click_action":"FCM_PLUGIN_ACTIVITY"
"icon":"fcm_push_icon",
},
"data":{
"type":"Something",
},
"to":"/topics/all",
"priority":"high",
"restricted_package_name":""
}
Any help would be very much appreciated.
You seem to be missing the data.wasTapped part in your subscribe. Here, try this:
this.fcm.onNotification().subscribe(data => {
if (data.wasTapped) {
alert('Received in background');
alert(JSON.stringify(data));
} else {
alert('Received in foreground');
alert(JSON.stringify(data));
}
});

Notification can not display correctly when app in background ( React Native )

I have an app that using Firebase push remote notification, one client send notification message like below:
body: JSON.stringify({
'to' : 'token',
'notification' : {
'title' : ' ' + this.currentUser.email + ' send you a message !',
'body' : text
},
'data': {
'senderName' : this.currentUser.email,
'senderUid': this.currentUser.uid
}
})
and one client implement the method that receive notification :
firebase.notifications().onNotification((notification) => {
const showNotification = new firebase.notifications.Notification()
.setNotificationId('notificationId')
.setTitle(notification.title)
.setBody(notification.data.text)
.android.setChannelId('channel_id_foreground')
.android.setSmallIcon('ic_launcher');
firebase.notifications().displayNotification(showNotification)
});
When my app running on foreground, the notification show normally, but when in background, it can receive in notification tray, but it not display that notification to the screen of device.
This is how the notification show:
I want the notification can display like:
Addition: If I close app by swipe out and send the notification, my app is going to be crashed.
Anybody can help me ?
As mentioned in the RN Firebase docs, when your app is in the background or closed, the notification is handled and displayed by the OS, so your onNotification() method is never called, so the notification channel is never set. According to the android developer docs notifications without a channel will not appear.
Here's what worked for me: if you want the notification to appear as a heads-up notification in android, modify your message body to include your channel ID, like this:
body: JSON.stringify({
'to' : 'token',
'notification' : {
'title' : ' ' + this.currentUser.email + ' send you a message !',
'body' : text
},
'data': {
'senderName' : this.currentUser.email,
'senderUid': this.currentUser.uid
},
'android': {
'priority': 'high',
'notification': {
'channel_id': 'channel_id_foreground',
},
}
})

Resources