0

I have been trying to get this to work, but am new to NodeJS. I suspect the issue is due to async, but am not familiar with how it works.

The idea behind this code is that it monitors a firebase database change and sends an email to the users. I am getting everything from the change snapshot, and using the values to check another table for user data. The request is not returning before the email gets sent and I am unsure why.

Edit I should specify that the email function sgMail is firing off before I get the results from the requests. I've tried putting a delay, but I am still not getting the result to return in time.

Here's my index.js

 // The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
var requestify = require('requestify');

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

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


// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.packingListEmail = functions.database.ref('Order/{orderID}')
   .onUpdate(event => {

  // Grab the current value of what was written to the Realtime Database.
  const eventSnapshot = event.data;

  //Here You can get value through key
  var shipperInfo = eventSnapshot.child("fk_shipper_id").val();
  var travelerInfo = eventSnapshot.child("fk_traveler_id").val();

  //Print value of string
  console.log(shipperInfo);

  //Get Shipper Info

  const shipperPath = 'https://shlep-me-f516e.firebaseio.com/User/'+shipperInfo+'.json';

  requestify.get(shipperPath)
     .then(function(response) {
          // Get the response body (JSON parsed or jQuery object for XMLs)
          shipperResult = response.getBody();
          console.log(shipperResult.email);
      return shipperResult;
      });

  function getTravelerData() {
      return new Promise(resolve => {
          requestify.get('https://shlep-me-f516e.firebaseio.com/User/' + travelerInfo + '.json')
             .then(function (response) {
              resolve(response.getBody())
          });
      });
    }

  var TravelD = getTravelerData();


  //Send an email

  const msg = {
      to: 'andrew@shlepme.com',
      from: 'support@shlepme.com',
      subject:  'New Follower',
      // text: `Hey ${toName}. You have a new follower!!! `,
      // html: `<strong>Hey ${toName}. You have a new follower!!!</strong>`,

      // custom templates
      templateId: 'd1ccfeb9-2e2d-4979-a3ca-c53975fe486e',
      substitutionWrappers: ['%', '%'],
      substitutions: {
          '%shipper_name%': "Test",
          'traveler_name': TravelD.name
          // and other custom properties here
        }
      };

      console.log('Sending email');
      console.log(TravelD);
      return sgMail.send(msg)
});

Any ideas? I have been trying to figure this out.

  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – str Feb 20 '18 at 10:52
  • So when I looked at my stack trace, it appears that the results are returning after the sgMail function is executed. I tried putting a delay on the sgMail, but it still won't hold off until the requests are returned. – Andrew Shamah Feb 20 '18 at 11:25
  • Please, correctly indent your code. – Rafael Paulino Feb 20 '18 at 11:29
  • Should be formatted now. – Andrew Shamah Feb 20 '18 at 11:36

1 Answers1

1

It seems that you need to understand about Promises first.

When you start using promises you will need to ALWAYS use them and chain one with the other.

So I would rewrite your code like this: (not tested)

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require("firebase-functions");
var requestify = require("requestify");

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

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

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);

exports.packingListEmail = functions.database
    .ref("Order/{orderID}")
    .onUpdate(event => {
        // Grab the current value of what was written to the Realtime Database.
        const eventSnapshot = event.data;

        //Here You can get value through key
        var shipperInfo = eventSnapshot.child("fk_shipper_id").val();
        var travelerInfo = eventSnapshot.child("fk_traveler_id").val();

        //Print value of string
        console.log(shipperInfo);

        //Get Shipper Info
        const shipperPath = "https://shlep-me-f516e.firebaseio.com/User/" + shipperInfo + ".json";

        requestify.get(shipperPath)
            .then(function(response) {
                // Get the response body (JSON parsed or jQuery object for XMLs)
                var shipperResult = response.getBody();
                console.log(shipperResult.email);
                return shipperResult;
            })
            .then(function (shipperResult) {
                //Send an email
                const msg = {
                    to: "andrew@shlepme.com",
                    from: "support@shlepme.com",
                    subject: "New Follower",
                    // text: `Hey ${toName}. You have a new follower!!! `,
                    // html: `<strong>Hey ${toName}. You have a new follower!!!</strong>`,

                    // custom templates
                    templateId: "d1ccfeb9-2e2d-4979-a3ca-c53975fe486e",
                    substitutionWrappers: ["%", "%"],
                    substitutions: {
                        "%shipper_name%": "Test",
                        traveler_name: shipperResult.name
                        // and other custom properties here
                    }
                };
                console.log("Sending email");
                console.log(shipperResult);
                return sgMail.send(msg);
            });
    });
Rafael Paulino
  • 570
  • 2
  • 9