Reputation: 1087
Try to run the function in Firebase Cloud Function once Cloud Function data generates. Actually, I want to run sendEmail
triggered by adding the events
collection's data. But the events occur several times not once.
I use mailgun
for sending an email.
exports.sendEmail = functions.firestore
.document("events/{eventId}")
.onCreate((snap, context) => {
const data = snap.data();
const { uid } = data;
usersRef.doc(uid).onSnapshot((user) => {
firestoreRef
.collection("followers")
.where("uid", "==", uid)
.get()
.then((snapshot) => {
snapshot.docs.map((snapshot) => {
const follower = snapshot.data();
mailgunClient.messages
.create("mg.xxxx.com", {
from: "Excited User <[email protected]>",
to: follower.email,
subject: Hello,
text: "test",
html: "<p>test</p>",
})
.then((msg) => console.log("msg", msg))
.catch((err) => console.log("error", err));
});
});
});
}
return true;
}
Upvotes: 0
Views: 116
Reputation: 317712
If you want to perform a Firstore query a single time, don't use onSnapshot
. That sets up a listener on a document that gets triggered whenever the document changes. You almost certainly want to use get()
instead, which performs a query a single time.
Also, you are not returning a promise that resolves when all the asynchronous work is complete. That is required for all Cloud Functions that are not HTTP functions. The promise is how Cloud Functions knows when it's safe to terminate and clean up all work, as described in the documentation. get()
returns a promise, so you should use that in addition to other promises for async work that you start. If you don't handle promises correctly in your function, it will not behave the way you expect.
Upvotes: 1