Firebase Firestore批处理提交:批处理指令是否按指定顺序执行?

时间:2020-04-15 16:06:22

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

我正在基于Firestore和Cloud Functions开发一个类似/不同的帖子系统。目前,我正在设置一个Cloud Function,当应用程序用户查看帖子列表时将执行该功能。该Cloud Function的目的是计算每个帖子的喜欢次数,总结同一帖子所有者的每个帖子的喜欢次数,并将每个帖子所有者的所有帖子的喜欢次数保存到数据库中文档。

所以:

  1. 我遍历所有用户文档,并将所有帖子的点赞次数设置为0。这是一个初始化。我使用批量更新。

  2. 然后,我遍历所有喜欢的对象。在RAM中,对于每个帖子所有者,我都会计算出他创建的每个帖子的喜欢次数之和。我使用JS数组操作。

  3. 然后,我遍历JS数组,该数组包含与所有帖子的赞次数相关联的帖子所有者的ID,并将数据库计数器设置为所有帖子的赞次数为价值。我使用批量更新。

如果不清楚,下面提供了代码。

我的问题是:由于我首先将所有用户文档的计数器初始化为0,然后影响其中一些用户文档的计数器的良好值,因此我实际上需要确保在进行初始化之前将0初始化完成。休息批更新。是这样吗?

exports.sortUsersByUsersPostsLikes = functions.https.onCall((data, context) => {
    if(!context.auth) {
        throw new functions.https.HttpsError('failed-precondition', 'The function must be called while authenticated.');
    }

    const batch = admin.firestore().batch();
    const users = admin_firestore.collection('users');
    const likes = admin_firestore.collection('likes_of_users_posts');
    users.get().then(function(users_docs) {
        users_docs.forEach(user_doc => {
            batch.update(user_doc.ref, "number_of_likes_of_users_posts", 0);
        });

        return likes.get();

    }).then(function(likes_docs) {
        const map_users_id_with_number_of_likes = [];
        likes_docs.forEach(like_doc => {
            if(!(like_doc.data().post_owner in map_users_id_with_number_of_likes)) {
                map_users_id_with_number_of_likes[like_doc.data().post_owner] = 0;
            }
            map_users_id_with_number_of_likes[like_doc.data().post_owner] += 1;
        });
        Object.keys(map_users_id_with_number_of_likes).forEach((k) => {
            const user = admin_firestore.collection('users').doc(k);
            batch.update(user, "number_of_likes_of_users_posts", map_users_id_with_number_of_likes[k]);
        }); 
        return batch.commit();

    }).catch(function(error) {
        console.log("UNABLE TO SORT THE USERS");
        console.log(error);
        throw new functions.https.HttpsError('unknown', 'An error occurred when trying to sort the users.');
    });

});

1 个答案:

答案 0 :(得分:2)

批处理和事务一次完成,要么原子完成,要么根本不完成。没有命令。如果您两次设置字段的值,则只有在构建批处理时指定的最后一个值才会生效。

如果您要询问可能会因文档更新而发生的Cloud Functions触发器,则永远无法保证这些触发器的顺序。