I have only limited experience with Javascript promises. The app tracks the availability of volunteer firefighters, they can change their availability status from a mobile app or web portal. The cloud function should execute any time a firefighter updates their status. I want the function to do a full count of all firefighters with status: "Available"
and then also count drivers and officers within that group.
Then I will check the end totals and if any of the three values is below a set threshold then a push notification is sent to all users notifying them that numbers are getting low.
The problem I have is that the database call admin.firestore().collection('users').where("status", "==", "Available").get()
and the push notification function admin.messaging().send(message)
both return promises.
If I don't nest the promises then the messages sends before the availability count is completed (as expected). If I nest the send message within the .then( snapshot => {
is get lots of ESLint warnings thrown at me about not nesting promises
What's the best way to implement this? I feel I know what I need to do, I just don't know how to do it.
index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const cors = require('cors')({ origin: true });
exports.sendPushNotification = functions.firestore
.document('users/{userId}')
.onUpdate((snap, context) => {
// This function checks the number of available firefighters each time any firefighter
// changes their status. If the numbers are below the minimums specified then a push
// notification is sent to all users alerting them of low muster numbers.
let count = admin.firestore().collection('users').where("status", "==", "Available").get()
.then(snapshot => {
let Available = 0;
let Drivers = 0;
let Officers = 0;
snapshot.forEach(doc => {
if (doc.data().driver) {
Drivers++;
}
if (doc.data().officer) {
Officers++
}
Available++
});
return {total: Available, drivers: Drivers, officers: Officers}
}).catch( (error) => {
return console.log(error);
})
message = {
topic: "MVFB",
notification: {
title: "Warning Low Numbers",
body: `Critial availability - Available: ${count.total} Drivers: ${count.drivers} Officers: ${count.officers}`
},
android: {
priority: "high",
notification: {
color: "#FF0000",
sound: "emergency.m4a",
channel_id: "emergency_message"
}
},
apns: {
payload: {
aps: {
sound: "Emergency.aiff"
}
}
},
};
admin.messaging().send(message)
.then((response) => {
console.log('Notification sent successfully:',response);
return true;
})
.catch((error) => {
console.log('Notification sent failed:',error);
return false;
});
return true
});