I’m implementing Firebase Cloud Messaging for an app for shops I am building.
After getting a message from a client, I would like to notify all the admins of that shop. For that, I fetch the doc of shop that the message was sent to, grab an array with the IDs of all the admins, and then for each ID (uid) I fetch the token which I’ve stored in firestore.
All the tokens get pushed into an array, and once I am done gathering all the tokens, I start sending the notifications.
The problem I am facing is that the function continues without waiting for the tokens to be fetched, so it evaluated the tokens array to be empty and finishes without sending any notification.
I know it because of logs I’ve added.
This is my cloud function:
exports.sendNotifications = functions.firestore
.document("messages/{messageId}")
.onCreate(async (snapshot) => {
// Notification details.
let text = snapshot.data().message_body || "";
if (text.length > 100) {
text = text.substring(0, 97) + "...";
}
const payload = {
notification: {
title: `הודעה חדשה מ${snapshot.data().name}`,
body: text,
// icon:
// snapshot.data().profilePicUrl || "/images/profile_placeholder.png",
// click_action: `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com`,
},
};
const shopID = snapshot.data().shop_id;
const shopData = await admin
.firestore()
.collection("shops")
.doc(shopID)
.get();
const shopAdminsArray = shopData.data()?.admins;
console.log("shopAdminsArray is ", shopAdminsArray);
const tokens: string[] = [];
shopAdminsArray.forEach(async (shopAdmin: string) => {
const user = await admin
.firestore()
.collection("fcm_tokens")
.doc(shopAdmin)
.get();
console.log("user.data()?.token is ", user.data()?.token);
if (user.data()?.token) {
tokens.push(user.data()?.token);
}
});
console.log("tokens.length is ", tokens.length);
if (tokens.length > 0) {
// Send notifications to all tokens.
const response = await admin.messaging().sendToDevice(tokens, payload);
await cleanupTokens(response, tokens);
functions.logger.log(
"Notifications have been sent and tokens cleaned up."
);
}
});
I consistently get the log saying tokens.length is 0
and only after that a log saying user.data()?.token is xxxxxxxxxxxxx