从云功能内的firebase读取

时间:2017-06-09 19:21:01

标签: javascript firebase firebase-realtime-database

任何人都可以帮我确定为什么firebase不会从云功能中返回值? 从数据库更改中读取数据似乎很简单,但是当根据请求执行http时,firebase函数会挂起并最终超时。

exports.getTotalPrice = functions.https.onRequest((req, res) => {
  var data = "";
   req.on('data', function(chunk){ data += chunk})
   req.on('end', function(){
       req.rawBody = data;
       req.jsonBody = JSON.parse(data);
       res.end(next(req.jsonBody));
   })
});
function next(json) {
  var total = 0;
  for(var i = 0; i < json.products.length; i++) {
    //Get product by UPC
    console.log(order.products[i].upc);
    codeRef.orderByKey()
      .equalTo(order.products[i].upc)
        .once('value', function(snap) {
          console.log(snap.val()); // returns `null`
          return (snap.val()[0].msrp);
    })
    //Multiply the price of the product by the quantity
    console.log(order.products[i].quantity);

    //add it to the total price
  }
}

2 个答案:

答案 0 :(得分:2)

您正在运行多个异步功能,但在完成后您无法通知您的功能。该函数需要返回一个在这里成功的承诺。

另请注意,如果数据库调用失败,它将在此处静默执行。因此,您应该捕获错误并报告这些错误。

另请注意,您将分发的JSON数据存储为数组,probably shouldn't

另请注意,当您使用.orderByKey().equalTo()时,您正在使用.child(upc)

所以你在这里得到的是一团糟。你需要花一些时间在guidesamples - 如果不这样做的话,你会花很多时间像这样捶打。

要获得起点,请将代码集减少到最简单的用例,并按预期运行:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.testDbOp = functions.https.onRequest((req, res) => {
  return admin.database()
     .ref('/foo')
     .once('value')
     .then(snap => res.send(JSON.stringify(snap.val()))
     .catch(e => console.error(e));
});

一旦你有了这个工作,如果你想异步获取几个值,你可以使用Promise.all()来实现,如下所示:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.testDbOp = functions.https.onRequest((req, res) => {
  const promises = [];
  const output = {};
  const jsonData = {....};
  jsonData.products.forEach(product => {
     promises.push( codeRef.child(product.upc).once('value')
       .then(snap => output[product.upc] = snap.val()[0].msrp);
  });
  return Promise.all(promises).then(() => res.send(JSON.stringify(output));
});

答案 1 :(得分:1)

看起来你根本就没有调用数据库。我只看到functions.https.onRequest()这是一个http触发器https://firebase.google.com/docs/functions/http-events

如果你想调用数据库,它必须更像functions.database.ref('/').onWrite(event => {}),以便引用数据库https://firebase.google.com/docs/functions/database-events

onWrite指的是数据库中该点的任何类型的更改,而不仅仅是写入数据库。 https://firebase.google.com/docs/functions/database-events#reading_the_previous_value