Cloud Functions for Firebase onWrite 触发器:snapshot.val 不是函数 [英] Cloud Functions for Firebase onWrite trigger: snapshot.val is not a function

查看:16
本文介绍了Cloud Functions for Firebase onWrite 触发器:snapshot.val 不是函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在同一个 index.js 文件中创建了几个函数,即 sendEmailsendEmailByDbStatusChangesendEmailConfirmation.

I created few functions in the same index.js file, which is sendEmail, sendEmailByDbStatusChange and sendEmailConfirmation.

sendEmail- 通过 HTTP/API 调用

sendEmail- To be call via HTTP/API

sendEmailByDbStatusChange - 在值更改时监听 DB,但操作是硬编码的

sendEmailByDbStatusChange - listening to DB while value change, but the action is hardcoded

sendEmailConfirmation- 在值更改时列出到 DB,操作以快照为准.

sendEmailConfirmation- Listing to DB while value change, the action subject to the snapshot.

以下是我的代码:

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 不是函数而无法顺利执行.

My problem is, after i deploy the code to firebase function, the console shows that the sendEmailConfirmation unable to execute smoothly due to event2.val is not a function.

我当前的代码结合了我的自定义代码和原始代码,其中 sendEmailConfirmation 是原始代码.当独立运行原始代码时,它确实有效(原始代码是 event 而不是 event2 用于快照).

My current code combined with my customize code and the original code, which sendEmailConfirmation is the original code. When run the original code independently it did work (original was event instead of event2 for the snapshot).

请指教.

推荐答案

您似乎已更新到 Firebase SDK for Cloud Functions v1.0,但没有升级您的代码以匹配.

It looks like you updated to v1.0 of the Firebase SDK for Cloud Functions, but didn't upgrade your code to match.

此文档页面中解释了整个过程.现在您正受到数据库触发器更改,这表明:

The entire process is explained in this documentation page. Right now you're being hit by the changes in database triggers, which shows that:

在早期版本中,event.dataDeltaSnapshot;现在在 v 1.0 中,它是一个 DataSnapshot.

Event data now a DataSnapshot

In earlier releases, event.data was a DeltaSnapshot; now in v 1.0 it is a DataSnapshot.

对于onWriteonUpdate事件,data参数有beforeafter 字段.其中每一个都是一个 DataSnapshot,其方法与 admin.database.DataSnapshot 中可用的方法相同.例如:

For onWrite and onUpdate events, the data parameter has before and after fields. Each of these is a DataSnapshot with the same methods available in admin.database.DataSnapshot. For example:

之前 (<= v0.9.1)

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
});

根据该示例,您将需要以下内容:

According to that example, you'll need something along these lines:

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));
});

这篇关于Cloud Functions for Firebase onWrite 触发器:snapshot.val 不是函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆