So I am using Firebase Functions for my server-side methods on my React.js app. I recently learned that some of my nodemailer functions were not functioning properly because I wasn't returning a promise properly.
For one of my larger projects, I need to go back and update my more complicated Firebase Functions to fit this new understand of returning from my listener functions. Before I dive into that, I need to know when do I 'return' from a function and how do Firebase Functions trigger?
In the example below, I have two emails that need to be sent out with two mutually inclusive conditional events (i.e. either event can occur on its own, together with the other event, or both not occur at all) Do I need to return from each of the if()
conditionals as I show in the example? Or do I need to just have one return statement at the end, outside all the if statements? Or a return only at the last if statement?
I ask this mainly because I want to make sure that if I am updating value1
and value2
in one Firestore call from the client-side, I don't want the userUpdatedHandler
listener function to terminate from the value1
return and never hit the value2
if conditional.
Example Firebase Function:
export async function userUpdatedHandler(change: functions.Change<DocumentSnapshot>, context: functions.EventContext) {
const previousValue = change.before.data();
const newValue = change.after.data();
if (previousValue == null) {
return console.log("No data for user before change");
}
if (newValue == null) {
return console.log("No data for user after change");
}
if(previousValue.value1 !== newValue.value1){
try {
console.log("Started try{}...")
// Template it
const htmlEmail =
`
<div>
Thanks for your interest.
<h3>Details:</h3>
<p><u>Your Email</u>: ${newValue.email}</p>
<p><u>Value1</u>: ${newValue.value1}</p>
</div>
`
// Config it
const transporter = nodemailer.createTransport({
host: "smtp.gmail.com",
port: 465,
secure: true,
auth: {
user: functions.config().email.user,
pass: functions.config().email.password
}
})
console.log("transporter = " + transporter)
// Pack it
const mailOptions = {
from: `help@mysite.com`,
to: `${newValue.email}`,
replyTo: `${newValue.email}`,
subject: `Value is ${newValue.value1}`,
text: newValue.message,
html: htmlEmail
}
// Send it
return transporter.sendMail(mailOptions);
} catch (error) {
console.error(error)
return;
}
}
if(previousValue.value2 !== newValue.value2){
try {
console.log("Started try{}...")
// Template it
const htmlEmail =
`
<div>
Thanks for your interest.
<h3>Details:</h3>
<p><u>Your Email</u>: ${newValue.email}</p>
<p><u>Value2</u>: ${newValue.value2}</p>
</div>
`
// Config it
const transporter = nodemailer.createTransport({
host: "smtp.gmail.com",
port: 465,
secure: true,
auth: {
user: functions.config().email.user,
pass: functions.config().email.password
}
})
console.log("transporter = " + transporter)
// Pack it
const mailOptions = {
from: `help@mysite.com`,
to: `${newValue.email}`,
replyTo: `${newValue.email}`,
subject: `Value is ${newValue.value2}`,
text: newValue.value2,
html: htmlEmail
}
// Send it
return transporter.sendMail(mailOptions);
} catch (error) {
console.error(error)
return;
}
}
}