首页 > 解决方案 > Firebase Firestore 批量提交:批量指令是否按指定顺序执行?

问题描述

我正在研究基于 Firestore 和 Cloud Functions 的类似/不一样的帖子系统。目前,我正在设置一个云函数,当应用程序用户查看帖子列表时将执行该函数。这个云函数的目的是统计每个帖子的点赞数,汇总同一帖子所有者的每个帖子的点赞数,并将每个帖子所有者的所有帖子的点赞数保存到帖子所有者的数据库中文档。

所以:

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

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

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

如果不清楚,可以在下面找到代码。

我的问题是:由于我首先将所有用户文档的计数器初始化为 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.');
    });

});

标签: firebasegoogle-cloud-firestoregoogle-cloud-functions

解决方案


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

如果您询问可能响应文档更新而发生的 Cloud Functions 触发器,则这些触发器永远不会有排序保证。


推荐阅读