Firebase Child_Added Successfully Triggering Nodemailer But Sending Duplicates (hosted on Heroku)

StackOverflow https://stackoverflow.com/questions/19719635

  •  02-07-2022
  •  | 
  •  

Question

I am building a website contact form. I have form submissions being added to Firebase via Angular js. When a new submission is submitted to Firebase I am using child_added in Node to trigger nodemailer. This is working fine, except that the entire submissions collection is being re-emailed whenever I restart the dev server, and multiple times daily in production on Heroku. How can I ensure that emails won't be sent more than once?

var myRoot = new Firebase('https://firebase.firebaseio.com/website/submissions');

myRoot.on('child_added', function(snapshot) {
    var userData = snapshot.val();
    var smtpTransport = nodemailer.createTransport("SMTP",{
        auth: {
            user: "email@gmail.com",
            pass: "password"
        }
    });

var mailOptions = {
    from: "Website <email@gmail.com>", // sender address
    to: "email@email.com.au", // list of receivers
    subject: "New  Website Lead", // Subject line
    html: "<p><strong>Name: </strong>" + userData.name + "</p>" + "<p><strong>Email: </strong>" + userData.email + "</p>" + "<p><strong>Phone: </strong>" + userData.phone + "</p>" + "<p><strong>Enquiry: </strong>" + userData.enquiry + "</p>" + "<p><strong>Submitted: </strong>" + userData.date + "</p>" // html body
};

smtpTransport.sendMail(mailOptions, function(error, response) {
    if(error) {
        console.log(error);
    }
    else {
        console.log("Message sent: " + response.message);
    }
    smtpTransport.close();
    });
});
Was it helpful?

Solution

The 'child_added' event probably isn't a good choice for this purpose. That event doesn't mean that a child has just been newly added to some collection in Firebase; it triggers for every child that loads from Firebase when your ref has child objects, in addition to triggering when a child is newly added. So every time you load that collection (e.g. when you restart your server) your mailer is called for every child that loads (hence the duplication).

You are probably better off sending a traditional http request to trigger the mailer from your angular action when a new submission is added.

I suppose you could add a field indicating whether or not the child has already been mailed, and only mail children that haven't been on a 'child_added' event. But this seems inelegant to me.

OTHER TIPS

Every time a child is added, move the child to a different branch of your firebase (or simply delete the child if you don't need a record of the event).

on('child_added', function(oldSnap) {
    eventHistoryRef.push(oldSnap.val());
    oldSnap.ref().remove();
    // use nodemailer
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top