javascript - 一旦 ("child_added")在非现有节点上不会失败但超时

标签 javascript firebase-realtime-database google-cloud-functions

首先,我不确定是否存在真正的问题,但我想我会分享我的推理。

我使用 Firebase 作为数据库/后端,用于归档来自家里各种传感器的所有数据,并在托管中使用带有炫酷图形的 UI。因此,每 10 分钟我就会推送来自各个房间的各种数据(温度、湿度、二氧化碳水平、照明度……)。我有近 3 年的可用数据(所以我的基地有很多节点)

所以我的数据库结构是这样的:

root
  readings
    room_id
      GUID
        time
        temp
        hum
        lum

几年来,我在家里托管了一个 PHP 脚本,用于检查每个 Readings/room_id 中的最新项目是否具有不太旧的时间值(不超过 11 分钟)。几天前我将其翻译为 Firebase 云函数,得到了这样的结果:

exports.monitor = functions.https.onRequest((req, res) => {
  const tstamp = Math.floor(Date.now() / 1000);
  var sensors = ["r01", "r02", "r03", "r04", "r05"];
  var promiseArray = [];
  var result = {};
  for (var i = 0; i < sensors.length; i++) {
    console.log('Adding promise for ' + sensors[i]);
    promiseArray.push(admin.database().ref('/readings/' + sensors[i]).limitToLast(1).once("child_added"));
  }
  Promise.all(promiseArray).then(snapshots => {
    console.log('All promises done : ' + snapshots.length);
    res.set('Cache-Control', 'private, max-age=300');
    for (var i = 0; i < snapshots.length; i++) {
      differenceInMinutes = (tstamp - snapshots[i].val().time) / 60;
      result[sensors[i]] = {current: tstamp,
                            sensor: snapshots[i].val().time,
                            diff: Math.round(differenceInMinutes * 10) / 10};
      if (differenceInMinutes < 11) {
        result[sensors[i]]['status'] = "OK";
      } else {
        result[sensors[i]]['status'] = "KO";
      }
    }
    return res.status(200).json(result);
  }).catch(error => {
    console.error('Error while getting sensors details', error.message);
    res.sendStatus(500);
  });
});

代码运行良好。所以我的问题是:如果我在传感器数组中添加另一个房间 ID,而该房间 ID 不存在于数据库的“读数”内,我想我会得到一个错误( promise 失败),而不是我只得到一个巨大的超时错误,我不知道不希望 Firebase Cloud Functions 出现这种超时(以避免任何不必要的成本)。

这正常吗?我的代码有错吗?我是否必须首先获取“readings/room_id”的浅快照检查它是否存在并检查是否有 child ?

非常感谢您的帮助。

编辑:在弗兰克的帮助下,我修复了我的代码,这是修改后的版本:

exports.monitor = functions.https.onRequest((req, res) => {
  const tstamp = Math.floor(Date.now() / 1000);
  var sensors = ["r01", "r02", "r03", "r04", "r05"];
  var promiseArray = [];
  var result = {};
  for (var i = 0; i < sensors.length; i++) {
    console.log('Adding promise for ' + sensors[i]);
    promiseArray.push(admin.database().ref('/readings/' + sensors[i]).limitToLast(1).once("value"));
  }
  Promise.all(promiseArray).then(queryResults => {
    console.log('All promises done : ' + queryResults.length);
    res.set('Cache-Control', 'private, max-age=300');
    queryResults.forEach((snapshots, i) => {
      snapshots.forEach((snapshot) => {
        var currentData = snapshot.val();
        differenceInMinutes = (tstamp - currentData.time) / 60;
        result[sensors[i]] = {current: tstamp,
                              sensor: currentData.time,
                              diff: Math.round(differenceInMinutes * 10) / 10};
        if (differenceInMinutes < 11) {
          result[sensors[i]]['status'] = "OK";
        } else {
          result[sensors[i]]['status'] = "KO";
        }
      });
    });
    return res.status(200).json(result);
  }).catch(error => {
    console.error('Error while getting sensors details', error.message);
    res.sendStatus(500);
  });
});

最佳答案

child_added 事件仅在存在子节点时触发。如果该位置下没有子节点(或与查询匹配),它将不会触发。

为了确保您在没有子项的情况下也收到通知,您应该监听 value 事件:

for (var i = 0; i < sensors.length; i++) {
  console.log('Adding promise for ' + sensors[i]);
  var query = admin.database().ref('/readings/' + sensors[i]).limitToLast(1).once("value")
  promiseArray.push(query);
}

由于 value 事件可能与单个快照中的多个子项匹配(尽管您的查询仅请求单个子项),因此您需要循环遍历生成的快照的子项:

Promise.all(promiseArray).then((queryResults) => {
  console.log('All promises done : ' + queryResults.length);
  res.set('Cache-Control', 'private, max-age=300');
  queryResults.forEach((snapshots) => {
    snapshots.forEach((snapshot) => {
      differenceInMinutes = (tstamp - snapshot.val().time) / 60;
      ...

关于javascript - 一旦 ("child_added")在非现有节点上不会失败但超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44589414/

相关文章:

javascript - 如何在另一个字符之前插入一个字符?

javascript - 如何预加载iframe

ios - 应用程序中收藏夹功能的最佳实践

java - Firebase 连接在 SpringBoot 中的 Linux 上不起作用

firebase批量更新和onWrite触发同步

ios - Firebase 云函数始终返回 Null

javascript - 将图像加载到织物 Canvas 背景

javascript - TypeError : _this. props.editAp 不是一个函数

javascript - Firebase 云函数 - TypeError : Cannot read property 'data' of undefined when data exists

javascript - 如何重构检查图像(用作 css 背景法师)是否存在以返回 bool 值的函数?