I have the following structure in firestore.
• conversations - {convid}
messages - {messageId}
field array offline [user ids]
• users - {userid} - devices - {deviceids}
So the usecase is whenever a new message is sent by a user, a triggered cloud function checks the offline array containing the userids of all offline users in the group.
Now while iterating and later sending a push to offline users, the iteration only shows multiple queries to the user on the last index of the array in the for loop.
The logs in cloud function are
The array of offline users is => [ '919XXXXX5565', '919XXXXX9334', '9190XXXXX608','919XXXXX1818', '919XXXXX9974', '9197XXXXX661', '9181XXXXX854' ]
2:56:22.043 AM Current user id: 919XXXXX5565
2:56:22.044 AM Current user id: 919XXXXX334
2:56:22.044 AM Current user id: 9190XXXXX608
2:56:22.044 AM Current user id: 919XXXXX1818
2:56:22.044 AM Current user id: 919XXXXX9974
2:56:22.044 AM Current user id: 9197XXXXX661
2:56:22.044 AM Current user id: 9181XXXXX854
2:56:22.046 AM Successfully prepared token list false
2:56:22.151 AM Function execution took 5097 ms, finished with status: 'ok'
2:56:22.188 AM No matching documents. for => 9181XXXXX854
2:56:22.190 AM No matching documents. for => 9181XXXXX854
2:56:22.229 AM No matching documents. for => 9181XXXXX854
2:56:22.231 AM No matching documents. for => 9181XXXXX854
2:56:22.233 AM No matching documents. for => 9181XXXXX854
2:56:22.237 AM No matching documents. for => 9181XXXXX854
My Code
var outputList = [];
var promises = [];
return admin.firestore().collection('conversations').doc(conversationDocId).get();
.then(document =>{
let offline = []
if(!document.exists){
return false;
} else{
try{
offline = document.data().offline;
console.log("The array of offline users is =>", offline);
}catch(offlineError){
console.error("offline array does not exist" + offlineError);
}
for(uid of offline) {
console.log("Current user id: " + uid);
let promise = admin.firestore().collection("users").doc(uid).collection('devices').get()
.then(snapshot => {
if (snapshot.empty) {
console.log('No matching documents. for =>', uid);
}
snapshot.forEach(doc => {
try {
token = doc.data().rt
outputList.push(token);
} catch (tokenfetcherror) {
console.error("unable to fetch token for =>", uid);
}
});
return;
}).catch(errtoken => {
console.error('Error getting documents', errtoken);
});
promises.push(promise);
}
Promise.all(promises).then(() => {
return outputList;
}).catch(err => {
return err;
})
}
return false;
})
I picked this from https://stackoverflow.com/a/57739544/1468797
Promise.all(). Returningfalseis not the thing to do when you have nested promises.