I am building an application where people can host events. It allows for users to follow the events and all the event followers can chat in a group. I am storing the FCM token for push notifications in a user collection in Firestore. But when I send the notification my current logic is not quite optimal and it takes several minutes for the notification to send to each user as I am first getting all user's tokens for each user's document and then combing those tokens in a list and send push notification to each token using a loop in my cloud function. I think it takes time for sending the messages and the group chat does not seem to be real-time because of that computation.
What I thought is to store the FCM tokens of each user inside every event he follows. So that when there is a chat message the list of tokens is fetched from the specific event and they are sent a multicast notification. But here again, I am not sure if it is a good approach because I will need to keep track of refreshed tokens and update the tokens in each document where it exists. Let's say a user has joined 50 events and on app launch, his FCM token got refreshed now I will have to run a cloud function that will see if the token is renewed it should loop through all of those 50 events and update his token.
I want to know what can be the best approach for this use case. Below is the code that I am using:
exports.sendNotification = functions.firestore
.document("event/{eventid}/{chat}/{chatid}")
.onCreate((snap, context) => {
processData(snap, context);
return null;
});
async function processData(snap, context) {
const doc = snap.data();
const eventID = context.params.eventid;
const senderID = doc.sender;
var senderName = doc.senderName;
await admin
.firestore()
.collection("event")
.doc(eventID)
.get()
.then(value => {
var joinedBy = value.data()["joinedBy"];
joinedBy.forEach(item => {
getTokens(uid, senderID, doc, eventName, senderName);
});
});
}
async function getTokens(uid, senderID, doc, eventName, senderName) {
await admin
.firestore()
.collection("people")
.doc(uid)
.get()
.then(value => {
var token = value.data()["pushToken"];
if (uid != senderID) {
if (token) {
const payload = {
notification: {
title: `${eventName} : ${senderName}`,
body: doc.text,
badge: "1",
sound: "default"
},
};
sendMessage(token, payload);
} else {
console.log("Can not find pushToken target user");
}
} else {
console.log("uid and sender id is same so notification not sent");
}
});
}