【问题标题】:Synchronously iterate through firestore collection同步遍历 Firestore 集合
【发布时间】:2020-03-23 16:34:21
【问题描述】:

我有一个 firebase 可调用函数,可以对集合中的文档进行一些批处理。

步骤是

  1. 将文档复制到单独的集合中并存档
  2. 根据文档中的数据向第三方服务运行 http 请求
  3. 如果2成功,删除文档

我无法强制代码同步运行。我无法弄清楚正确的等待语法。

async function archiveOrders  (myCollection: string) {

//get documents in array for iterating
const currentOrders = [];
console.log('getting current orders');
await db.collection(myCollection).get().then(querySnapshot => {
    querySnapshot.forEach(doc => {
        currentOrders.push(doc.data());
    });
});

console.log(currentOrders);

//copy Orders
currentOrders.forEach (async (doc) => {

    if (something about doc data is true ) {
        let id = "";
        id = doc.id.toString();
        await db.collection(myCollection).doc(id).set(doc);
        console.log('this was copied: ' + id, doc);
    }

});

}

【问题讨论】:

    标签: node.js typescript firebase google-cloud-firestore


    【解决方案1】:

    现在我不熟悉 firebase,所以如果我访问数据的方式有问题,您必须告诉我。

    您可以使用await Promise.all() 等待所有promise 解决后再继续执行该函数,Promise.all() 将同时触发所有请求,并且不会等待一个完成后再触发下一个请求。

    虽然async/await 的语法看起来是同步的,但事情仍然是异步发生的

    async function archiveOrders(myCollection: string) {
      console.log('getting current orders')
      const querySnapshot = await db.collection(myCollection).get()
      const currentOrders = querySnapshot.docs.map(doc => doc.data())
    
      console.log(currentOrders)
    
      await Promise.all(currentOrders.map((doc) => {
        if (something something) {
          return db.collection(myCollection).doc(doc.id.toString()).set(doc)
        }
      }))
    
      console.log('copied orders')
    }
    

    【讨论】:

      【解决方案2】:

      为了解决这个问题,我做了一个单独的函数调用,它返回一个我可以等待的承诺。 我还利用了 QuerySnapshot,它返回此 QuerySnapshot 中所有文档的数组。有关用法,请参阅here

      // from inside cloud function
      // using firebase node.js admin sdk
      
      const current_orders = await db.collection("currentOrders").get();
      
      for (let index = 0; index < myCollection.docs.length; index++) {
        const order = current_orders.docs[index];
        await archive(order);
      }
      
      
      async function archive(doc) {
      
          let docData = await doc.data();
      
      if (conditional logic....) {
          try {
            // await make third party api request
            await db.collection("currentOrders").doc(id).delete();
      
          }
          catch (err) {
            console.log(err)
          }
      } //end if
      
      } //end archive
      

      【讨论】:

        猜你喜欢
        • 2018-12-10
        • 1970-01-01
        • 2014-04-11
        • 2021-08-15
        • 2018-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多