我正在基于Firestore和Cloud Functions开发一个类似/不同的帖子系统。目前,我正在设置一个Cloud Function,当应用程序用户查看帖子列表时将执行该功能。该Cloud Function的目的是计算每个帖子的喜欢次数,总结同一帖子所有者的每个帖子的喜欢次数,并将每个帖子所有者的所有帖子的喜欢次数保存到数据库中文档。
所以:
我遍历所有用户文档,并将所有帖子的点赞次数设置为0。这是一个初始化。我使用批量更新。
然后,我遍历所有喜欢的对象。在RAM中,对于每个帖子所有者,我都会计算出他创建的每个帖子的喜欢次数之和。我使用JS数组操作。
然后,我遍历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.');
});
});
答案 0 :(得分:2)
批处理和事务一次完成,要么原子完成,要么根本不完成。没有命令。如果您两次设置字段的值,则只有在构建批处理时指定的最后一个值才会生效。
如果您要询问可能会因文档更新而发生的Cloud Functions触发器,则永远无法保证这些触发器的顺序。