sometime the notification is delayed for no reason and then comes all together iam using https://pub.dev/packages/flutter_local_notifications https://pub.dev/packages/firebase_messaging
here is my code from cloud functions ( nodejs )
exports.messageTrigger = functions.firestore.document('/Messages/{messageID}').onCreate(
async (snapshot, context) => {
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() string.slice(1);
}
var currentRoomUsers = snapshot.data().members;
currentRoomUsers.forEach( (userID) => {
db.collection('Users').doc(userID).get().then(async(doc)=>{
if(doc.exists && doc.id != snapshot.data().senderID){
const message = {
data: {
title: `New message from ${capitalizeFirstLetter(snapshot.data().room)}`,
body: snapshot.data().type == 'm.text' ? 'Sent a new message' : snapshot.data().type == 'm.start'? 'Invited you for a call' : snapshot.data().type == 'm.image' ? 'Sent an image' : 'Sent a new message'
},
tokens: doc.data()['Device_token'],
android: {
priority: 'high',
},
priority: "high",
}
await admin.messaging().sendMulticast(message);
}else {
console.log("No such document!");
}
}).catch((error)=>{
console.log("Error getting document:", error);
});
}
);
}
);
CodePudding user response:
Firestore documents are fetched asynchronously and the sendMulticast()
statement here may run before all the documents are fetched. Also, you must terminate Cloud Functions by returning a Promise. Since you are using an async
function, try refactoring the code with async-await
syntax as shown below:
exports.messageTrigger = functions.firestore
.document("/Messages/{messageID}")
.onCreate(async (snapshot, context) => {
try {
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() string.slice(1);
}
const currentRoomUsers = snapshot.data().members;
// use Promise.all() to fetch all documents
const customRoomUsersSnap = await Promise.all(
currentRoomUsers.map((user) =>
db.collection("Users").doc(user).get()
)
);
const messagePromises = [];
// Iterate over all documents and add a message for every existing document
customRoomUsersSnap.forEach((userSnap) => {
if (userSnap.exists) {
const message = {
data: {
title: `New message from ${capitalizeFirstLetter(
snapshot.data().room
)}`,
body:
snapshot.data().type == "m.text"
? "Sent a new message"
: snapshot.data().type == "m.start"
? "Invited you for a call"
: snapshot.data().type == "m.image"
? "Sent an image"
: "Sent a new message",
},
tokens: userSnap.data()["Device_token"],
android: {
priority: "high",
},
priority: "high",
};
messagePromises.push(admin.messaging().sendMulticast(message));
} else {
console.log(`User ${userSnap.ref.id} doc does not exist`);
}
});
// Send all messages simultaneously.
return Promise.all(messagePromises);
} catch (error) {
console.log(error);
// return Promise<null> in case of an error
return null;
}
});