通过Cloud Function访问Firestore

时间:2019-05-01 13:36:37

标签: node.js firebase google-cloud-firestore google-cloud-functions

所以我在同一文件中有2个Cloud Functions:

exports.Auth = functions.region('europe-west1').https.onRequest((req, res) =>

exports.IPN = functions.region('europe-west1').https.onRequest((req, res) =>

在我的Auth函数开始处添加以下代码时,它会按预期向Firestore添加一个新文档,但是,当我在IPN函数开始处添加相同的代码时,当前正在通过Paypal调用IPN模拟器,它什么也不做,没有错误。

  let pin = RandomPIN(10, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
  var userRef = db.collection('Users').doc(pin);
  var setWithOptions = userRef.set({ Activated: false }, { merge: true });
  console.log("PIN: "+pin);

到底是怎么回事,我一定想念什么吗?

谢谢。

更新

以下是日志,首先在中间的两行加上注释,然后未注释enter image description here。这似乎是默默地失败了,我只是不确定是什么原因引起的。

使用完成功能更新:

exports.IPN = functions.region('europe-west1').https.onRequest((req, res) =>
{
  console.log("IPN Notification Event Received");

  let pin = RandomPIN(10, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
  var userRef = db.collection('Users').doc(pin);
  var setWithOptions = userRef.set({ Activated: false }, { merge: true });
  console.log("PIN: "+pin);

  if (req.method !== "POST")
  {
    console.error("Request method not allowed.");
    res.status(405).send("Method Not Allowed");
  }
  else
  {
    console.log("IPN Notification Event received successfully.");
    res.status(200).end();
  }

  let ipnTransactionMessage = req.body;
  // Convert JSON ipn data to a query string since Google Cloud Function does not expose raw request data.
  let formUrlEncodedBody = querystring.stringify(ipnTransactionMessage);
  // Build the body of the verification post message by prefixing 'cmd=_notify-validate'.
  let verificationBody = `cmd=_notify-validate&${formUrlEncodedBody}`;

  console.log(`Verifying IPN: ${verificationBody}`);

  let options = {
    method: "POST",
    uri: getPaypalURI(),
    body: verificationBody,
  };

  // POST verification IPN data to paypal to validate.
  request(options, function callback(error, response, body)
  {
    if(!error && response.statusCode === 200)
    {
      if(body === "VERIFIED")
      {
        console.log(`Verified IPN: IPN message for Transaction ID: ${ipnTransactionMessage.txn_id} is verified.`);
        SendPIN(ipnTransactionMessage.payer_email, pin);
      }
      else if(body === "INVALID")
        console.error(`Invalid IPN: IPN message for Transaction ID: ${ipnTransactionMessage.txn_id} is invalid.`);
      else
        console.error("Unexpected reponse body.");
    }
    else
    {
      console.error(error);
      console.log(body);
    }
  });
});

1 个答案:

答案 0 :(得分:1)

实际上,这是一个Promises链接问题,也是一个由于request库引起的问题:request本机支持回调接口,但不返回promise,这是您在Cloud中必须执行的操作功能。

我建议您观看Doug的这些Firebase官方视频:https://www.youtube.com/watch?v=7IkUgCLr5oA&t=28shttps://www.youtube.com/watch?v=652XeeKNHSk,它们解释了这个关键概念。

您可以使用request-promisehttps://github.com/request/request-promise)和rp()方法来“返回符合Promises / A +的常规承诺”。

目前尚不清楚SendPIN()在做什么。让我们假设它返回一个Promise。如果是这样,您可以按照以下方式修改代码:

//....
const rp = require('request-promise');
//....

exports.IPN = functions.region('europe-west1').https.onRequest((req, res) => {
  console.log('IPN Notification Event Received');

  let pin = RandomPIN(
    10,
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  );
  var userRef = db.collection('Users').doc(pin);

  if (req.method !== 'POST') {
    console.error('Request method not allowed.');
    res.status(405).send('Method Not Allowed');
  } else {
    let ipnTransactionMessage;
    userRef
      .set({ Activated: false }, { merge: true })
      .then(() => {
        console.log('PIN: ' + pin);
        ipnTransactionMessage = req.body;
        // Convert JSON ipn data to a query string since Google Cloud Function does not expose raw request data.
        let formUrlEncodedBody = querystring.stringify(ipnTransactionMessage);
        // Build the body of the verification post message by prefixing 'cmd=_notify-validate'.
        let verificationBody = `cmd=_notify-validate&${formUrlEncodedBody}`;

        console.log(`Verifying IPN: ${verificationBody}`);

        let options = {
          method: 'POST',
          uri: getPaypalURI(),
          body: verificationBody
        };
        // POST verification IPN data to paypal to validate.
        return rp(options);
      })
      .then(response => {
        //Not sure what you will get within the response object...
        console.log(
          `Verified IPN: IPN message for Transaction ID: ${
            ipnTransactionMessage.txn_id
          } is verified.`
        );
        return SendPIN(ipnTransactionMessage.payer_email, pin); //It is not clear what SendPIN is doing, let's make the assumption it returns a Promise...
      })
      .then(() => {
        res.send('Success');
        return null;
      })
      .catch(err => {
        console.error(
          `Invalid IPN: IPN message for Transaction ID: ${
            ipnTransactionMessage.txn_id
          } is invalid.`
        );
        res
          .status(500)
          .send(
            'Error: ' +
              err +
              ` - Invalid IPN: IPN message for Transaction ID: ${
                ipnTransactionMessage.txn_id
              } is invalid.`
          );
        return null;
      });
  }
});