首页 > 解决方案 > 如何遍历 Firebase 文档以查找匹配的文档,然后提取名称?

问题描述

我有一个 Firebase 设备集合,其中包含一个名为 state 的字段。

我希望我的代码遍历每个文档,找到状态为 0 的任何一个文档,然后将该状态更新为 2。最后,我想获取状态已更改的设备的名称。

运行我的代码后,它确实找到并正确更新了集合中的文档,但是我无法返回Promise.resolve(..)存储文档名称的文档。

它似乎只输出“事务失败:未找到状态为 0 的设备”,意思return Promise.reject('No devices with state 0 found');是在不应该达到的时候达到。

这是我的代码:

  let deviceRef = db.collection("devices");

  let transaction = db.runTransaction(t => {
    return t.get(deviceRef)
      .then(snapshot => {
        snapshot.forEach(doc => {
          console.log(doc.id, '=> state:', doc.data().state);
          if (doc.data().state == 0) {
            doc.ref.update({ state: 2 });
            return Promise.resolve(doc.id + ' has been changed to state 2');
          }
        });
        return Promise.reject('No devices with state 0 found');
      });
  }).then(result => {
    console.log('Transaction success', result);
  }).catch(err => {
    console.log('Transaction failure:', err);
  });

代码确实到达doc.ref.update({state: 2});了,因为我可以看到 Firebase 集合被正确修改,但return Promise.resolve(doc.id + ' has been changed to state 2');似乎没有被“捕获”。

我究竟做错了什么?

我怀疑我错误地使用了 Promise。一些研究让我相信我需要使用Promise.all或某种形式的地图来处理forEach.

标签: javascriptfirebasepromisegoogle-cloud-firestore

解决方案


你的问题在于你的回报Promise.resolve。它只会返回到forEach并且return.reject总是会执行。我强烈建议添加一些控制台日志,以便您可以看到这种情况。此外,您还有多个可能会更新的文档,所以我不确定您到底是如何看待个人Promise.resolve工作的,也许您打算在它保持一系列承诺的情况下做类似以下的事情?

.then(snapshot => {
    var promises = [];
    snapshot.forEach(doc => {
        console.log(doc.id, '=> state:', doc.data().state);
        if (doc.data().state == 0) {
            doc.ref.update({
                state: 2
            });
            //this is only returning into the forEach
            //return Promise.resolve(doc.id + ' has been changed to state 2');
            promises.push(Promise.resolve(doc.id + ' has been changed to state 2'));
        }
    });
    if(promises.length){
        return Promise.all(promises);
    }
    return Promise.reject('No devices with state 0 found');
});

推荐阅读