Firebase Cloud functions - collapsible IOS notifications - ios

I use cloud functions to send notifications. It works, but I want collapsible messages. How can I do it? Here is my current function:
exports.sendNotifications = functions.database
.ref("/users/{userId}/data")
.onWrite(event => {
const userId = event.params.userId;
if (!event.data.val()) {
return;
}
const payload = {
notification: {
title: `Hey`,
body: 'It's your turn!'
//icon: receiver.photoURL
}
};
const options = {
collapseKey: 'myturnkey'
};
return admin
.database()
.ref(`users\/${userId}\/data\/notificationkey`)
.once('value')
.then(data => {
console.log('inside key', data.val());
if (data.val()) {
return admin.messaging().sendToDevice(data.val(), payload, options);
}
});
});
I tried "collapseKey" and "collapse_key" in options but none of them works, I still receive notifications every time my function is called, so I get a list of notifications on my iphone whereas I want only one.
EDIT
I also tried the parameter "apns-collapse-id" according to the FCM messages documentation, but when when I try to deploy the functions the console says " apns-collapse-id: 'myturnkey', ^ SyntaxError: Unexpected token -"
Thank you,
Alexandre

You can do this, or manipulate current notifications in other ways, using the registration.getNotifications() API which gives you access to all the currently visible notifications for your web app.
But you need to write this code in your Service-worker
see this documention for merging-notifications

Related

Firebase Cloud Function Push Notification Really Slow

I have an iOS app that sends a time sensitive push notification from an event via Cloud Firestore-triggered function.
In my function, I do a simple get operation prior to sending out the push notification, and it gets delivered from 30 sec up to 1 min. Can anyone advise on improving the speed?
I've looked at the online documentation talking about setting a minimum # of instances to reduce a cold start. I've also looked at this SO answer. As someone that's new to this, I admittedly am having difficulty following and pinpointing my advised next step. Any help and guidance would be extremely appreciated.
exports.pushNotification = functions.firestore.document('/users/{userId}').onUpdate((change, context) => {
var recipientUid = context.params.userId;
return admin.firestore().collection('users').doc(recipientUid).get().then(doc => {
const userData = doc.data();
var fcmToken = userData.fcmToken;
var message = {
notification: {
title: sendingTitle,
body: sendingMessage
},
apns : {
payload : {
aps : {
badge : 1,
sound: "default"
}
}
},
token: fcmToken
};
admin.messaging().send(message)
.then((response) => {
console.log('Successfully sent push notification message:', response);
return;
})
.catch((error) => {
console.log('Error sending message:', error);
return;
});
})
});
One possible cause is that you don't correctly manage the life cycle of your Cloud Function: as a matter of fact you are not returning the Promises chain, as shown below (see the comments in the code):
exports.pushNotification = functions.firestore.document('/users/{userId}').onUpdate((change, context) => {
var recipientUid = context.params.userId;
return admin.firestore().collection('users').doc(recipientUid).get()
.then(doc => {
const userData = doc.data();
var fcmToken = userData.fcmToken;
var message = { ... };
return admin.messaging().send(message) // !!! See the return here
}) // And see also that we close the then block here
.then((response) => {
console.log('Successfully sent push notification message:', response);
return;
})
.catch((error) => {
console.log('Error sending message:', error);
return;
});
});
For more details on how to correctly manage the life cycle, I would suggest you watch the 3 videos about "JavaScript Promises" from the Firebase video series as well as read the following doc. Also, reading the doc on how to chain Promises will help.

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.

Firebase Cloud Messaging Localization Arguments Error

I am providing the following Payload to admin.messaging().sendToDevice(fcmToken, message);
var message = {
notification: {
title_loc_key: "NOTIFICATION_TITLE",
body_loc_key: "NOTIFICATION_BODY",
body_loc_args: ["Body Arg"],
sound: 'default'
}
};
However this generates the following error:
Messaging payload contains an invalid value for the "notification.body_loc_args" property. Values must be strings.
I don't see how "Body Arg" is not a string. I also tried specifying a string but this also did not work...
Any idea what the problem could be?
Thanks
I'm not sure what version of the Admin SDK is being used, but if the code is on the latest, then only title and body go in the notification object. Other values go under the payload key. Here's an example in the guide. Here is the API reference. Your message variable should look somewhat like this:
var message = {
apns: {
payload: {
aps: {
alert: {
title_loc_key: "NOTIFICATION_TITLE",
body_loc_key: "NOTIFICATION_BODY",
body_loc_args: ["Body Arg"],
sound: 'default'
}
}
}
}
};
If the code doesn't use the latest version of the Admin SDK, I recommend updating.

how to trigger push notifications of firebase from an ios device using swift3

I am new iOS developer.
I am using firebase and I am trying to make a chat application in which I need to notify user when he/she receives any message.
For this purpose I tried firebase push notifications, but couldn't be able to trigger them when other user send the message.
The only way I found is using firebase console to send push notification, but it doesn't fulfill my requirements.
I've just configured local notifications.
Please guide me how can we trigger push notifications without using the firebase console.
Finally found the solution after struggling for almost 1 month.
These are the basic steps
Firs off all you need to make sure that you have an active apple developers account
just enable firebase push notifications
here ie the link of youtube video for this step
Now your app is set up for firebase remote notifications but we can only trigger them from the firebase console so here is the tricky part. here is the link of video to enable firebase console on your mac
for the first time it will be good to see this video too because in this video they'll learn to write code in node.js and deploy it to the firebase.
Now if anyone wants to make an API instead of making a trigger then here is a code of API which sends the notification to other user by getting his FCM token from the firebase...
You can modify it according to your need
i am finding it difficult to post code in its exact form but the code starts from here
const functions = require('firebase-functions');
const admin =require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const ref=admin.database().ref();
exports.sendNotification=functions.https.onRequest((req,res) =>{
const id = req.query.id
const title = req.query.title
const message = req.query.message
const key = req.query.key
// admin.database.ref()
const payload ={
notification: {
title: title,
body: message,
//badge: '1',
sound: 'default',
}
};
console.log('Param [key] is '+key);
const keys = [] ;
ref.child('keys').once('value')
.then(snap => {
snap.forEach(childSnap => {
const loopKey=childSnap.val().key;
keys.push(loopKey);
})
return keys;
})
.then(keys=>{
//console.log('Keys in database : '+keys.join());
if(keys.indexOf(key)>-1)
{
if(!key || !id || !message)
{
res.status(400).send('Bad request');
}
else{
ref.child('users').child(id).child('fcmToken').once('value')
.then(snapshot => {
if (snapshot.val()){
const token = snapshot.val()
console.log(token);
return admin.messaging().sendToDevice(token,payload).then(response =>{
res.status(200).send('Notification sent')
});
}
});
}
}
else
{
console.log("In-valid key : "+key);
res.status(400).send('Bad request');
}
})
.catch(error => {
res.send(error)
});
});
ends at this point
this is the function to store your fcm to database
func postToken(token: String, id: String){
print("FCM Token \(token)")
let ref = Database.database().reference().child("users").child(id)
ref.child("fcmToken").setValue(token)
}
here is the function which i used to trigger this API
func sendNotification(id: String, title: String, message: String){
var url = "your URL"
var urlComponents = NSURLComponents(string: url)
urlComponents?.queryItems = [
URLQueryItem(name: "key", value: self.apiKey),
URLQueryItem(name: "id", value: id),
URLQueryItem(name: "title", value: title),
URLQueryItem(name: "message", value: message)
]
Alamofire.request((urlComponents?.url)!).responseJSON { (response) in
print(response.response)
print(response.response)
print(response.result)
}
}
the above API was written according to my database structure. you can change it easily for your own structure.
after doing this all you'll be able to send your notifications after hitting the URL
Hope it will give a nice idea to you people to work with your own notifications according to your need.
I was able to send Push Notifications from my code using PushNotificationSender class from this article -
https://www.iosapptemplates.com/blog/ios-development/push-notifications-firebase-swift-5

Firebase Cloud Messaging push notification not being sent to device

This is what my log looks like when my push notification gets called on
I am currently working on creating push notification set up for a user to user setting for the iPhone. I am currently using Firebase, so naturally I turned to Firebase Cloud Messaging to get this done. This is my setup in the functions that I am deploying to my Firebase. Is there something that I am doing wrong in here that would result in the notification not being sent to the device? I appreciate any help, and if there is any more needed information I would be happy to supply it.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
// Listens for new messages added to messages/:pushId
exports.pushNotification = functions.database.ref('/messages/{pushId}').onWrite( event => {
console.log('Push notification event triggered');
// Grab the current value of what was written to the Realtime Database.
var valueObject = event.data.val();
console.log(valueObject)
if(valueObject.photoUrl != null) {
valueObject.photoUrl= "Sent you a photo!";
}
// Create a notification
const payload = {
notification: {
title:valueObject.toId,
body: valueObject.text || valueObject.photoUrl,
sound: "default"
},
};
//Create an options object that contains the time to live for the notification and the priority
const options = {
priority: "high",
timeToLive: 60 * 60 * 24
};
return admin.messaging().sendToTopic("pushNotifications", payload, options);
if(!data.changed()){
});
exports.pushNotification = functions.database.ref('/messages/{pushId}').onWrite( event => {
const data = event.data;
console.log('Push notification event triggered');
return;
}
});
I noticed that you are exposing the same function twice. That is also an issue. Also I suggest you to promisify the admin.messaging, so that you can handle and check for errors.
let topic = "pushNotifications";
admin.messaging().sendToTopic(topic, payload, options)
.then(function(response) {
console.log("Successfully sent message:", response);
console.log("Topic: " + topic);
res.status(200).send("success");
})
.catch(function(error) {
console.log("Error sending message:", error);
res.status(500).send("failure");
});
Send this jsone on your post parameter in registration_ids field you have to post array of your All device token that you want to send push notification
This is post request method body
{ "registration_ids" : [Send Array of Device Token],
"data" :
{
"image_url" : "send your image here"
"message" : "Send your message here" },
"notification" :
{
"title" : "APP Name",
"sound" : "default",
"priority" : "high"
}
}
Here is post URL
https://fcm.googleapis.com/fcm/send
and send key="Your Authorization key" in request HttpHeader field
Take reference for basic setup form here for cloud messaging
https://firebase.google.com/docs/cloud-messaging/ios/client

Resources