Облачные функции для триггера onWrite в Firebase: snapshot.val не является функцией - PullRequest
0 голосов
/ 01 мая 2018

Я создал несколько функций в одном файле index.js, который sendEmail, sendEmailByDbStatusChange и sendEmailConfirmation.

sendEmail - вызов по HTTP / API

sendEmailByDbStatusChange - прослушивание БД при изменении значения, но действие жестко закодировано

sendEmailConfirmation - Перечисление в БД при изменении значения, действие зависит от моментального снимка.

Ниже мои коды:

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({
  service: 'gmail',
  auth: {
    user: gmailEmail,
    pass: gmailPassword,
  },
});

// Sends an email confirmation when a user changes his mailing list subscription.
exports.sendEmail = functions.https.onRequest((req, res) => {
  if (req.body.subject === undefined || req.body.recipient === undefined) {
    // This is an error case, as "message" is required.
    //res.status(400).send('subject/body/recipient is missing!');
    return false
  } else {
    const mailSubject = req.body.subject;
    const mailHtmlBody = req.body.htmlBody;
    const mailRecipient = req.body.recipient;



    const mailOptions = {
      from: '"Food Ninja." <foodninjaapp@gmail.com>',
      to: mailRecipient,
      subject: mailSubject,
      html: mailHtmlBody
    };

    //res.status(200).send('Success: ' + mailSubject + ' to ' + mailRecipient);

    return mailTransport.sendMail(mailOptions)
      .then(() => {
        console.log(`${mailSubject}subscription confirmation email sent to: `, mailRecipient)
        return res.status(200).send('Success: ' + mailSubject + ' to ' + mailRecipient)
      })
      .catch((error) => console.error('There was an error while sending the email:', error));
  }
});

exports.sendEmailByDbStatusChange = functions.database.ref('/users/{uid}').onWrite((event) => {
  //const snapshot = event.data;
  //const val = snapshot.val();

  //if (!snapshot.changed('subscribedToMailingList')) {
  //  return null;
  //}

  const mailSubject = 'Sending email with Cloud Function - by DB onWrite Trigger';
  const mailHtmlBody = '<h1>Hello Jerry</h1><p>If you receiving this means that you have successfully deployed a customized firebase function</p><p>Be Happy!<br><br>Food Ninja Team</p>';
  const mailRecipient = 'admin@phd.com.my';

  const mailOptions = {
    from: '"Food Ninja." <foodninjaapp@gmail.com>',
    to: mailRecipient,
    subject: mailSubject,
    html: mailHtmlBody
  };

  //const subscribed = val.subscribedToMailingList;

  // Building Email message.
  //mailOptions.subject = subscribed ? 'Thanks and Welcome!' : 'Sad to see you go :`(';
  //mailOptions.text = subscribed ? 'Thanks you for subscribing to our newsletter. You will receive our next weekly newsletter.' : 'I hereby confirm that I will stop sending you the newsletter.';

  return mailTransport.sendMail(mailOptions)
    .then(() =>
      console.log(`${mailSubject}subscription confirmation email sent to: `, mailRecipient)
      //return res.status(200).send('Success: ' + mailSubject + ' to ' + mailRecipient)
    )
    .catch((error) => console.error('There was an error while sending the email:', error));
});

exports.sendEmailConfirmation = functions.database.ref('/users/{uid}').onWrite((event2) => {
  console.log(event2)
  console.log(event2.val())
  console.log(event2.val().data)
  console.log(event2.data)
  console.log(event2.data.val())
  const snapshot = event2.data;
  console.log(snapshot)
  const val = snapshot.val();
  console.log(val)

  if (!snapshot.changed('subscribedToMailingList')) {
    return null;
  }

  const mailOptions = {
    from: '"Spammy Corp." <noreply@firebase.com>',
    to: val.email,
  };

  const subscribed = val.subscribedToMailingList;

  // Building Email message.
  mailOptions.subject = subscribed ? 'Thanks and Welcome!' : 'Sad to see you go :`(';
  mailOptions.text = subscribed ? 'Thanks you for subscribing to our newsletter. You will receive our next weekly newsletter.' : 'I hereby confirm that I will stop sending you the newsletter.';

  return mailTransport.sendMail(mailOptions)
    .then(() => console.log(`New ${subscribed ? '' : 'un'}subscription confirmation email sent to:`, val.email))
    .catch((error) => console.error('There was an error while sending the email:', error));
});

Моя проблема в том, что после того, как я развернул код в функции firebase, консоль показывает, что sendEmailConfirmation не может выполняться гладко из-за event2.val, не является функцией.

Мой текущий код в сочетании с моим кодом настройки и исходным кодом, который sendEmailConfirmation является исходным кодом. При запуске исходного кода независимо он работал (оригинал был event вместо event2 для снимка).

Пожалуйста, сообщите.

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Начиная с версии 1.0.0 модуля firebase-functions, база данных onWrite теперь доставляет объект Change вместо объекта DataSnapshot в качестве первого параметра , О всех критических изменениях в 1.0.0 вы можете прочитать в документации . Вместо этого следует использовать этот объект изменения, чтобы выбрать, хотите ли вы проверить содержимое базы данных до или после изменения, которое его вызвало.

0 голосов
/ 01 мая 2018

Похоже, вы обновились до версии 1.0 Firebase SDK для облачных функций, но не обновили свой код до соответствия.

Весь процесс описан в этой странице документации . Прямо сейчас вас поражают изменения в триггерах базы данных , которые показывают, что:

Данные о событиях теперь DataSnapshot

В более ранних выпусках event.data был DeltaSnapshot; сейчас в версии 1.0 это DataSnapshot.

Для событий onWrite и onUpdate параметр data имеет поля before и after. Каждый из них представляет собой DataSnapshot с теми же методами, доступными в admin.database.DataSnapshot. Например:

До (<= v0.9.1) </strong>

exports.dbWrite = functions.database.ref('/path').onWrite((event) => {
  const beforeData = event.data.previous.val(); // data before the write
  const afterData = event.data.val(); // data after the write
});

Сейчас (v1.0.0)

exports.dbWrite = functions.database.ref('/path').onWrite((change, context) => {
  const beforeData = change.before.val(); // data before the write
  const afterData = change.after.val(); // data after the write
});

Согласно этому примеру вам понадобится что-то вроде этого:

exports.sendEmailConfirmation = functions.database.ref('/users/{uid}').onWrite((change, context) => {
  const snapshot = change.after;
  const val = snapshot.val();
  console.log(val)

  if (!snapshot.changed('subscribedToMailingList')) {
    return null;
  }

  const mailOptions = {
    from: '"Spammy Corp." <noreply@firebase.com>',
    to: val.email,
  };

  const subscribed = val.subscribedToMailingList;

  // Building Email message.
  mailOptions.subject = subscribed ? 'Thanks and Welcome!' : 'Sad to see you go :`(';
  mailOptions.text = subscribed ? 'Thanks you for subscribing to our newsletter. You will receive our next weekly newsletter.' : 'I hereby confirm that I will stop sending you the newsletter.';

  return mailTransport.sendMail(mailOptions)
    .then(() => console.log(`New ${subscribed ? '' : 'un'}subscription confirmation email sent to:`, val.email))
    .catch((error) => console.error('There was an error while sending the email:', error));
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...