Search code examples
javascriptfirebasegoogle-cloud-firestoregoogle-cloud-functionssendgrid

Firestore Cloud Function - Send E-Mail onCreate with SendGrid


I have a contact form which submits data to the Firestore Database. My intention is, that as soon as there's another entry in the collection requests, Firestore shall fire a function via Cloud Function, which contains the configuration for SendGrid, which again is supposed to send the data of this specific entry to an e-mail.

I've also tried to deploy this function, which was successful - but the console shows the following errors, which I reckon won't be the only one:

Cannot read property 'requestId' of undefined

const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp();

const SENDGRID_API_KEY = functions.config().sendgrid.key;

const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(SENDGRID_API_KEY);

exports.firestoreEmail = functions.firestore
  .document('requests/{requestId}')
  .onCreate(event => {

    const requestId = event.params.requestId;

    const db = admin.firestore();

    return db.collection('requests').doc(requestId)
      .get()
      .then(doc => {

        const requestId = event.params.requestId;

        const request = doc.data();

        const msg = {
          to: 'fuh@gmx.net',
          from: 'hello@angularfirebase.com',

          templateId: 'd-',
          substitutionWrappers: ['{{', '}}'],
          substitutions: {
            name: request.name,
            lastname: request.lastname,
            email: request.email,
            package: request.package,
            date: request.date,
            text: request.text
            // and other custom properties here
          }
        };

        return sgMail.send(msg)
      })
      .then(() => console.log('email sent!') )
      .catch(err => console.log(err) )


  });

Edit:

const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp();

const SENDGRID_API_KEY = functions.config().sendgrid.key;

const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(SENDGRID_API_KEY);

exports.request = functions.firestore
  .document('requests/{requestId}')
  .onCreate((snap, context) => {

    const db = admin.firestore();

    return db.collection('requests').doc(requestId)
      .get()
      .then(doc => {

        const requestId = snap.id;

        const request = doc.data();

        const msg = {
          to: 'fuhr@gmx.net',
          from: 'hello@angularfirebase.com',

          templateId: 'd-3cd6b40ad6674f33702107d2',
          substitutionWrappers: ['{{', '}}'],
          substitutions: {
            name: request.name,
            lastname: request.lastname,
            email: request.email,
            package: request.package,
            date: request.date,
            text: request.text
            // and other custom properties here
          }
        };

        return sgMail.send(msg)
      })
      .then(() => console.log('email sent!') )
      .catch(err => console.log(err) )


  });

Solution

  • The .onCreate() method doesn't return event, it returns the snapshot of the object and from it you get the id of the new object.

    So in your case, it has to be:

    exports.firestoreEmail = functions.firestore.document('requests/{requestId}')
      .onCreate((snap, context) => {
    
        const requestId = snap.id; // get the id
        const db = admin.firestore();
    
        return db.collection('requests').doc(requestId)
            .get()
            .then(doc => {
               const request = doc.data();
               const msg = {
                 to: 'fuhr@gmx.net',
                 from: 'hello@angularfirebase.com',
    
                 templateId: 'd-3cd6b40ad6674f33702107d2',
                 substitutionWrappers: ['{{', '}}'],
                 substitutions: {
                     name: request.name,
                     lastname: request.lastname,
                     email: request.email,
                     package: request.package,
                     date: request.date,
                     text: request.text
                     // and other custom properties here
                 }
             };
    
             return sgMail.send(msg)
         })
         .then(() => console.log('email sent!') )
         .catch(err => console.log(err) )
      });