首先,我不确定是否存在真正的问题,但我想我会分享我的推理。
我使用Firebase作为数据库/后端,用于归档来自家中各种传感器的所有数据以及具有托管的酷图的UI。因此,每隔10分钟,我会推出各种房间的各种数据(温度,湿度,二氧化碳水平,照明......)。我有近3年的数据可用(所以我的基地有很多节点)
所以我的数据库结构是这样的:
root
readings
room_id
GUID
time
temp
hum
lum
几年来,我在家中托管了一个PHP脚本,检查每个读数/ 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,那里面不存在&#34;读数&#34;在我的数据库中,我认为我会收到错误(失败的承诺),而我只有一个巨大的超时错误,我不希望Firebase云功能出现这种超时(以避免任何不必要的成本)。
这是正常的吗?我的代码错了吗?我必须首先获得一个浅层快照&#34;读数/ room_id&#34;检查它是否存在并检查是否有孩子?
非常感谢你的帮助。
编辑:在Frank的帮助下我修复了我的代码,这是修订版:
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);
});
});
答案 0 :(得分:1)
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;
...