Google cloud firestore Firebase云功能不需要等待forEach完成,然后再跳到下一个

Google cloud firestore Firebase云功能不需要等待forEach完成,然后再跳到下一个,google-cloud-firestore,google-cloud-functions,Google Cloud Firestore,Google Cloud Functions,正在尝试将集合的子集合复制到另一个集合中。下面的代码就是针对这一点的,但是从第一个代码跳到第二个代码,然后“完成”注销,之前没有任何注销 所以问题是这里什么是不正确的 exports = module.exports = functions.https.onRequest(async (req, res) => { let db = admin.firestore(); try { await db.collection("users"

正在尝试将集合的子集合复制到另一个集合中。下面的代码就是针对这一点的,但是从第一个代码跳到第二个代码,然后“完成”注销,之前没有任何注销

所以问题是这里什么是不正确的

exports = module.exports = functions.https.onRequest(async (req, res) => {
  
    let db = admin.firestore();

    try {
      await db.collection("users").get().then((query) => {
          return query.forEach(async (doc) => {
            console.log("Here");                  //This doesn't print
            const polCollection = await db.collection("users").doc(doc.id).collection("xyz").get();
          
            if (polCollection.docs.length > 0) {  //This checks if any subcollections
             
              for (const x of polCollection.docs) { //This copies them into a doc in the copy collection
                db.collection("CopyUsers")
                  .doc(doc.id)
                  .set({ x : x.data() }, { merge: true });
              }
            }
          });
        })
        .then(() => {
          console.log("Done");  //This is the only thing that prints in the console
          
            res.end();
         
        })
        .catch((e) => {
          console.log("e", e);
          
            res.end();
         
        });
    } catch (error) {
      console.log("error", error);
     
        res.end();
    
    }
});
在提出以下建议后,现在看来如下:

exports = module.exports = functions.runWith(runtimeOpts).https.onRequest(async (req, res) => {

  const promises = [];


    let count = 0;
    let size = 0;

    return await admin
      .firestore()
      .collection("testUsers")
      .get()
      .then((query) => {

        console.log("query length:", query.size); //prints x of users
        size = query.size;

        query.forEach(async (doc) => {
          const promise = async () => {
            console.log("Here", doc.id); //This doesn't print
            await admin
              .firestore()
              .collection("testUsers")
              .doc(doc.id)
              .collection("xyz")
              .get()
              .then(async (polCollection) => {
                if (polCollection.docs.length > 0) {
                  for (const x of polCollection.docs) {
                    
                    return await admin
                      .firestore()
                      .collection("testBackUpUsers")
                      .doc(doc.id)
                      .set(
                        { xyz: x.data()  },
                        { merge: true }
                      );
                  }
                } else {
                  return;
                }
              })
              .catch((e) => console.log("error from then after get xyz", e));
          };
          count++;
          return promises.push(promise);
        });
        return promises;
      })
      .then(async (promises) => {
        if (size <= count) {
          console.log("running return Promise.all(promises)", promises.length); //prints number of promises = users

          return Promise.all(promises);
        }
      })
      .catch((e) => console.log("err from the last catch", e));

});
exports=module.exports=functions.runWith(runtimeOpts).https.onRequest(async(req,res)=>{
常量承诺=[];
让计数=0;
设大小为0;
返回等待管理员
.firestore()
.collection(“testUsers”)
.get()
。然后((查询)=>{
console.log(“查询长度:”,query.size);//打印x个用户
size=query.size;
query.forEach(异步(doc)=>{
const promise=async()=>{
console.log(“Here”,doc.id);//这不打印
等待管理员
.firestore()
.collection(“testUsers”)
.doc(doc.id)
.集合(“xyz”)
.get()
.然后(异步(polCollection)=>{
如果(polCollection.docs.length>0){
for(polCollection.docs的常数x){
返回等待管理员
.firestore()
.collection(“testBackUpUsers”)
.doc(doc.id)
.设置(
{xyz:x.data()},
{merge:true}
);
}
}否则{
返回;
}
})
.catch((e)=>console.log(“获取xyz之后的错误”,e));
};
计数++;
回报承诺。推动(承诺);
});
回报承诺;
})
.然后(异步(承诺)=>{
if(size console.log(“err from the last catch”,e));
});

有什么想法吗?

不幸的是,
forEach
迭代器不支持
async/await
。即使您在其中编写了一个await,它也会在不等待执行的情况下运行

我建议使用
Promise.all
。这也会并行执行代码,并且完成得更快

如果您只想更改数据,您也可以使用
批处理
更改,但在您的示例中,您首先获取数据,然后更改它

下面是一个如何编写代码的示例:

exports=module.exports=functions.https.onRequest(异步(req,res)=>{
设db=admin.firestore();
常量承诺=[];
试一试{
const query=await db.collection(“用户”).get();
query.forEach((doc)=>{
控制台日志(“doc”,doc);
const promise=async()=>{
console.log(“Here”,doc.id);//这不打印
const polCollection=wait db
.收集(“用户”)
.doc(doc.id)
.集合(“xyz”)
.get();
如果(polCollection.docs.length>0){
//这将检查是否存在任何子集合
for(polCollection.docs的常数x){
//这会将它们复制到副本集合中的文档中
等待数据库
.collection(“复制用户”)
.doc(doc.id)
.set({x:x.data()},{merge:true});
}
}
};
承诺。推动(承诺);
});
console.log(“承诺”,承诺);
等待承诺。所有(承诺);
控制台日志(“完成”);
res.end();
}捕获(错误){
console.log(“错误”,error);
res.end();
}
});

谢谢,尝试过了,但仍然没有执行。我有一个相当大的集合,大约有5k个条目,可能这限制了函数的运行?是否有任何错误?没有错误,它会打印“完成”,但不会打印“此处”…有什么想法吗?你能用额外的日志更新你的代码吗?我在答案中更新了代码。也许你的
用户
集合是emoty。只是为了确保我们有一些东西。添加额外的日志,用户肯定不是空的,控制台。log('doc',doc)打印了很多日志,虽然不是全部,它也没有打印“Here”“``12:31:47.447 pm csvCopyColls函数执行耗时3457 ms,完成状态代码:200 12:31:47.441 pm csvCopyColls Done 12:31:47.363 pm csvCopyColls[AsyncFunction],12:31:47.355 pm csvCopyColls doc x几百个日志```