3
votes

I want to send email to user on update of status field of user to value (true) using firestore and cloud functions.

My case : I have a users(collections) which has more documents of userId(documents) and each document contains field and value. One of the field is status: true | false (boolean).

I want to send email to that user if status of that user change to true using cloud functions and sendgrid api.

users
   - dOpjjsjssdsk2121j131
        - id : dOpjjsjssdsk2121j131
        - status : false
   - pspjjsjssdsdsk2121j131
        - id : pspjjsjssdsdsk2121j131
        - status : false
   - yspjjsjssdsdsk2121j131
        - id : yspjjsjssdsdsk2121j131
        - status : false


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.sendEmail = functions.firestore.document('users/{userId}')
  .onUpdate((change, context) => {  
   const after = change.after.val();

    if(after.status === 'VERIFIED'){
      console.log('profile verified')
      const db = admin.firestore();

      return db.collection('users').doc(userId)
      .get()
      .then(doc => {
         const user = doc.data();
         const msg = {
           to: 'email',
           from: 'email',
           templateId: 'template id',
           dynamic_template_data: {
            subject: 'Profile verified',
            name: 'name',
        },
       };

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

    } 

  });
3
Could you provide information about what exactly is not working with your codeConstantin Beer

3 Answers

6
votes

You are getting your error because in Firestore where is no val().

Try to change your change.after.val() to change.after.data(), so your code looks like this:

exports.sendEmail = functions.firestore.document('users/{userId}')
  .onUpdate((change, context) => {  
   const after = change.after.data();

    if(after.status === 'VERIFIED'){
      console.log('profile verified')
      const db = admin.firestore();


      return db.collection('users').doc(context.params.userId)  // get userId
      .get()
      .then(doc => {
         const user = doc.data();
         const msg = {
           to: 'email',
           from: 'email',
           templateId: 'template id',
           dynamic_template_data: {
            subject: 'Profile verified',
            name: 'name',
        },
       };
       return sgMail.send(msg)
   })
   .then(() => console.log('email sent!') )
   .catch(err => console.log(err) )
    } 
  });
1
votes

All correct for the above answer except "context.params." is missing from (staffId)

Currently:

return db.collection('users').doc(userId)  // get userId

Should Be:

>     return db.collection('users').doc(context.params.userId)  // get userId

This will also answer the above comment:

how to get the userId before return.db.collection('users').doc(userId) . ? – Fortray Sep 6 '19 at 9:13
1
votes
you can compare the target field by before and after data, if your target field is not the same. It means the field value has changed.

    const beforedata=change.before.data()
const afterdata=change.after.data()

if(afterdata.status == beforedata.status){
// Status not changed
}else{
//status changed
}