TheBluerock
TheBluerock

Reputation: 53

Firebase - cloud function returns undefined

I am trying to build a mailer function taking advantage of nodemailer and firebase cloud functions:

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

const gmailEmail = functions.config().gmail.email;
const gmailPassword = functions.config().gmail.password;
const mailTransport = nodemailer.createTransport("smtps://gmailEmail:[email protected]");

const test = '[email protected]'

const APP_NAME = 'Dati fatturazione elettronica';

exports.sendDatas = functions.database.ref('/datiFatt/{pushId}').onCreate((data) => {
  console.log(data);

  const name = data.name;
  const pec = data.pec
  const id = data.id;

  return sendEmail(name, pec, id);
});

function sendEmail(name, pec, id) {
  const mailOptions = {
    from: `${gmailEmail}`,
    to: test
  };

  mailOptions.subject = `Data from ${name}!`;
  mailOptions.html = `${name} \n ${pec} \n ${id} `;

  return mailTransport.sendMail(mailOptions)
    .then(() => {
      return console.log('New email sent to:', test);
    });
}

But somehow this function returns 'undefined' in all its fields. Probably I am accessing the data in a wrong way.

Upvotes: 0

Views: 434

Answers (2)

Renaud Tarnec
Renaud Tarnec

Reputation: 83181

There are two places in your code that you should correct:

Firstly, since it seems you are using an old version of the Firebase SDK for Cloud Functions (i.e. < v 1.0, see https://firebase.google.com/docs/functions/beta-v1-diff#realtime-database) you get the data that was just added to the database by using the val() method of a DataSnapshot (data.data in your case), as follows:

exports.sendDatas = functions.database.ref('/datiFatt/{pushId}').onCreate((data) => {
  const name = data.data.val().name;
  const pec = data.data.val().pec
  const id = data.data.val().id;
  ....
});

Note that it would be clearer to name the parameter of the callback function as event instead of data and modify the code like:

exports.sendDatas = functions.database.ref('/datiFatt/{pushId}').onCreate((event) => {
  const name = event.data.val().name;
  ....
});

However, I would suggest that you upgrade to the latest version of the SDK and therefore use the latest syntax (....onCreate((snap, context) => {const name = snap.val().name; ....}); see the doc referenced above).

Secondly, for Cloud Functions triggered by events in the Real Time database (like other background functions) you must return a Promise to indicate to the platform when the Function is finished (or generated an error). So you should modify your function as follows:

function sendEmail(name, pec, id) {
  const mailOptions = {
    from: `${gmailEmail}`,
    to: test
  };
  mailOptions.subject = `Data from ${name}!`;
  mailOptions.html = `${name} \n ${pec} \n ${id} `;
  return mailTransport.sendMail(mailOptions);
 });
}

Upvotes: 1

sketchthat
sketchthat

Reputation: 2688

Your sendEmail function might be wrong. You're trying to return console.log.

Try adjusting to the below format;

function sendEmail(name, pec, id) {
  const mailOptions = {
    from: `${gmailEmail}`,
    to: test
  };

  mailOptions.subject = `Data from ${name}!`;
  mailOptions.html = `${name} \n ${pec} \n ${id} `;

  return mailTransport.sendMail(mailOptions)
    .then(() => {
      console.log('New email sent to:', test);

      return;
    });
}

Upvotes: 1

Related Questions