Firestore Cloud Function阵列循环-写入长延迟

时间:2019-04-19 14:50:35

标签: firebase google-cloud-firestore google-cloud-functions

我有一个cloud函数,该函数循环遍历一组uid,然后为每个uid创建一个写操作。正常写入几乎立即发生,但是在出现写入之前要等待很长时间。

我尝试了不同大小的数组。仅具有一个或两个uid的数组速度更快,但仍存在约5-6秒的延迟。

exports.addPostings = functions.firestore
    .document('posts/{postID}')
    .onCreate((snap, context) => {
    const newValue = snap.data();
    var uid = newValue.author.uid;
    let followers = [];
    var feedRef = db.collection("feedItems");
    var authorRef = db.collection("users").doc(newValue.author.uid);
    authorRef.get().then((doc) => {
        let data = doc.data();
        let post_count = data.postCount;
        authorRef.update({
            postCount: Number(post_count) + 1
        }).then(() => {
            authorRef.collection('followers').doc('content').get().then((doc) => {
                let data = doc.data();
                if (typeof data.uids != 'undefined') {
                    followers = data.uids;
                }
            }).then(() => {
                followers.forEach((fol) => {
                  feedRef.add({
                      createdAt: admin.firestore.FieldValue.serverTimestamp(), uid: fol, creatorUid: uid,
                      postId: context.params.postID, isResharedPost: false, wasViewed: false,
                      wasReshared: false, wasLiked: false, wasDirectlyShared: false
                  });
                });
            });
        });
    });
});

2 个答案:

答案 0 :(得分:1)

您应该在代码中修改几点:

  1. 您没有返回异步方法返回的承诺,这是编写Cloud Function代码时的关键,如Firebase官方视频系列中有关“ JavaScript承诺”的3个视频中所述:{ {3}}
  2. 您应该正确地兑现承诺
  3. 您应该使用批处理写入,如CuriousGeorge所述

以下修改应该可以解决问题(不过,尚未测试!):

exports.addPostings = functions.firestore
  .document('posts/{postID}')
  .onCreate((snap, context) => {
    const newValue = snap.data();
    var uid = newValue.author.uid;
    let followers = [];
    var feedRef = db.collection('feedItems');
    var authorRef = db.collection('users').doc(newValue.author.uid);

    return authorRef
      .get()
      .then(doc => {
        let data = doc.data();
        let post_count = data.postCount;
        return authorRef.update({
          postCount: Number(post_count) + 1
        });
      })
      .then(() => {
        return authorRef
          .collection('followers')
          .doc('content')
          .get();
      })
      .then(doc => {
        let data = doc.data();
        if (typeof data.uids != 'undefined') {
          followers = data.uids;

          let batch = db.batch();

          followers.forEach(fol => {
            const ref = feedRef.doc();
            batch.set(ref, {
              createdAt: admin.firestore.FieldValue.serverTimestamp(),
              uid: fol,
              creatorUid: uid,
              postId: context.params.postID,
              isResharedPost: false,
              wasViewed: false,
              wasReshared: false,
              wasLiked: false,
              wasDirectlyShared: false
            });
          });

          // Commit the batch
          return batch.commit();
        } else {
          return null;
        }
      });
  });

答案 1 :(得分:0)

此外,您还应该研究使用transaction.batched此处的内容。这使您可以定义一系列读/写,然后同时执行它们。此方法可能很慢的部分原因是您正在执行多个读/写操作(在处理过程中失败的情况下也很糟糕)。 https://firebase.google.com/docs/firestore/manage-data/transactions#transactions