对云功能中多个孩子的复杂查询

时间:2018-07-24 12:55:50

标签: node.js firebase firebase-realtime-database google-cloud-functions

这是我的Firebase数据库的结构:

/UserData
  /DeviceMgmt
      /Counters
          /NumberOfAll:
          /NumberOfSelected
          /TotalDownloaded
        ...
      /Devices
          /pushId1
            /uid
            /signOutTime
            /toSelect=true (optional)
            /downloaded
            /lastDownload

          /pushId2
          /pushId3
           ...

这是我的云功能:

exports.markDevicesForDownload = functions.database.ref('/UserData/DeviceMgmt/Counters/NumberOfSelected').onUpdate( (change) => {

   const changeRef = change.after.ref;              
   const deviceMgmtRef = changeRef.parent.parent;   // /UserData/DeviceMgmt

   if (change.after.val() === 0 ) { //NumberOfSelected gets 0 value

        return deviceMgmtRef.once('value')
            .then((snap) => {

                const devicesRef = snap.child('Devices').ref;

                var average;
                var numberOfAllDevices;
                var totalDownloaded;

                numberOfAllDevices = snap.child('Counters/NumberOfAll').val();
                totalDownloaded = snap.child('Counters/TotalDownloaded').val();
                average = Math.round(totalDownloaded/numberOfAllDevices);

                return devicesRef
                        .orderByChild('signOutTime')
                        .equalTo(0)
                        .once('value',(devices) => {
                        return devices.ref
                                .orderByChild('downloaded')
                                .endAt(average)
                                .once('value',(devices) => {
                                    devices.forEach((device) => {
                                        device.child('toSelect').ref.set(true);
                                    });
                        });
                });
            });

   } else {
       return false;
   }

});

该函数在计数器NumberOfSelected = 0时触发; 当在任何设备 pushId 下没有子 toSelect 时,就会发生这种情况。然后,对 downloaded 子项的查询将所有 downloaded 小于 average 的设备设置为 toSelect = true

我只想将设备限制为 signOutTime 等于0的设备。 不知何故该查询无法正常工作,并且考虑了所有设备。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

我会将所有异步任务推送到promise数组中,然后在所有任务完成时将它们全部返回:

exports.markDevicesForDownload = functions.database.ref('/UserData/DeviceMgmt/Counters/NumberOfSelected').onUpdate((change) => {
  const changeRef = change.after.ref;
  const deviceMgmtRef = changeRef.parent.parent; // /UserData/DeviceMgmt
  if (change.after.val() === 0) { //NumberOfSelected gets 0 value
    return deviceMgmtRef.once('value')
      .then((snap) => {
        const promises = [];
        const devicesRef = snap.child('Devices').ref;
        var average;
        var numberOfAllDevices;
        var totalDownloaded;
        numberOfAllDevices = snap.child('Counters/NumberOfAll').val();
        totalDownloaded = snap.child('Counters/TotalDownloaded').val();
        average = Math.round(totalDownloaded / numberOfAllDevices);
        const dR = devicesRef
          .orderByChild('signOutTime')
          .equalTo(0)
          .once('value', (devices) => {
            const dW = devices.ref
              .orderByChild('downloaded')
              .endAt(average)
              .once('value', (devices) => {
                devices.forEach((device) => {
                  if (device.child("signOutTime").val() === 0){
                    promises.push(device.child('toSelect').ref.set(true));
                  }
                });
              });
              promises.push(dW);
          });
          promises.push(dR);
          return Promise.all(promises);
      });
  } else {
    return false;
  }
});