Чтение из firebase внутри облачной функции

1

Может ли кто-нибудь помочь мне определить, почему 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
  }
}
Теги:
firebase
firebase-realtime-database

2 ответа

2
Лучший ответ

Вы выполняете несколько асинхронных функций, но вы не сообщаете свою функцию, когда они сделаны. Функция должна вернуть обещание, чтобы преуспеть здесь.

Обратите также внимание на то, что если вызов базы данных не удался, он будет делать это здесь молча. Поэтому вы должны фиксировать ошибки и сообщать об этом.

Также обратите внимание, что вы храните свои распределенные данные JSON в виде массивов, которых вы, вероятно, не должны.

Также обратите внимание, что вы используете .orderByKey().equalTo() когда вы можете просто использовать .child(upc).

Так что вы, по сути, здесь, беспорядок. Вам нужно потратить некоторое время в руководстве, и образцы --you собираются потратить много времени так, как если бы вы этого не сделали.

Для начальной точки уменьшите свой код до простейшего варианта использования, как и ожидалось:

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

Не похоже, что вы вообще вызываете базу данных. Я вижу только 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

  • 0
    Спасибо за ответ! Но вы перечислили (так же, как список документов Google) ссылку на .onWrite, я могу очень легко получить данные при записи, это получение данных без необходимости взаимодействия с отдельной базой данных. Это должно быть возможно, может быть, я просто не понимаю. Поскольку я инициирую это из http-запроса, он не может полагаться на транзакцию базы данных, которая произошла ранее. Это то, что смущает меня.
  • 0
    Если вы хотите внести изменения в базу данных на основе http-триггера, вы можете использовать Firebase Admin SDK для доступа к базе данных. См. Документацию здесь: firebase.google.com/docs/reference/admin/node. Вы также можете увидеть это в действии здесь: youtube.com/watch?v=3lzEgwiSs-M
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню