Javascript 如何在Firebase文档中循环查找匹配的文档,然后提取名称?

Javascript 如何在Firebase文档中循环查找匹配的文档,然后提取名称?,javascript,firebase,promise,google-cloud-firestore,Javascript,Firebase,Promise,Google Cloud Firestore,我有一个Firebase设备集合,其中有一个名为state的字段 我希望我的代码在每个文档中循环,找到任何一个状态为0的文档,并将该状态更新为2。最后,我想获取状态已更改的设备的名称 运行我的代码后,它确实在集合中正确地查找和更新文档,但是我无法返回存储文档名称的Promise.resolve(..) 它似乎只输出“事务失败:未找到状态为0的设备”,意思是返回Promise.reject(“未找到状态为0的设备”)在不应该的时候到达 这是我的密码: let deviceRef = db.co

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

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

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

它似乎只输出“事务失败:未找到状态为0的设备”,意思是
返回Promise.reject(“未找到状态为0的设备”)在不应该的时候到达

这是我的密码:

  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集合被正确修改,但是
返回Promise.resolve(doc.id+'已更改为状态2')似乎未被“捕获”

我做错了什么


我怀疑我不正确地使用了承诺。一些研究使我相信,我需要使用
承诺。所有
或某种形式的映射来处理
forEach
您的问题在于您是否返回
承诺。解决
。它只会返回到
forEach
,而
return.reject
总是会执行。我强烈建议添加一些控制台日志,以便您可以看到这种情况。另外,您有多个可能会更新的文档,因此我不确定您是如何看待个人的
承诺的。解决
工作的,也许您打算做如下的事情,其中包含一系列承诺

.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');
});

Brian,仅供参考,关于堆栈溢出,反勾引号用于标记代码片段,而不是一般强调。@DougStevenson理解,感谢tipI。现在看一下,我来试一试。promises数组是否会变得比1更大?谢谢你正在做一个
快照。forEach
对吗?你有多份文件?那么是吗?是的,对不起,我一试就知道问题的答案了。我只需要更新此事务中的一个设备。要做到这一点,我需要在一个
Promise.resolve
被推送到Promise数组后立即跳出forEach,对吗?我看到了forEach的突破,我想知道用try-catch和使用异常来“突破”是否一定是“坏”的。我试着使用的,但我认为快照是不合适的。谢谢,您可以自己使用for循环,而不是构建在快照上的for循环。那就很容易爆发了。或者跟踪一个变量,这样一旦它找到一个,forEach就会立即返回并且不再执行。