我想创造一个
WriteBatch
控制数据库中的一个动态引用。我的应用程序有一个简单的
User-Follow-Post-Feed
模型中,我希望我的用户在他的提要中看到他正在关注的所有用户的帖子。在研究Firebase示例(如
Firefeed
)还有很多关于堆栈溢出的帖子。
最佳想法是保持一条路径(
collection
在这种情况下)我存储
Ids
我的用户应该在他的提要中看到的帖子,这意味着控制复制并删除他关注/取消关注的所有用户的每个帖子。
我做了我的
Cloud functions
为了让它以原子的方式运行,一切都很好,但是当我试图做一个大规模的测试时,为一个试图跟踪他的用户添加了5000多个帖子(想看看
Cloud function
我看到批次限制为500次操作。因此,我所做的是将我的5000个id分割成多个小列表,并在每个列表中执行一个批次,永远不会超过500个限制。
但即使这样做,我仍然会遇到一个错误
I can't do more than 500 operations in a single commit
,我不知道是否是因为批处理同时执行,或者为什么。我想也许我可以一个接一个地执行,避免一次执行它们。但我仍然有一些麻烦。这就是我问题的原因。
以下是我的方法:
fun updateFeedAfterUserfollow(postIds: QuerySnapshot, userId: String) {
//If there is no posts from the followed user, return
if (postIds.isEmpty) return
val listOfPostsId = postIds.map { it.id }
val mapOfInfo = postIds.map { it.id to it.toObject(PublicUserData::class.java) }.toMap()
//Get User ref
val ref = firestore.collection(PRIVATE_USER_DATA).document(userId).collection(FEED)
//Split the list in multiple list to avoid the max 500 operations per batch
val idsPartition = Lists.partition(listOfPostsId, 400)
//Create a batch with max 400 operations and execute it until the whole list have been updated
idsPartition.forEach { Ids ->
val batch = firestore.batch().also { batch ->
Ids.forEach { id -> batch.set(ref.document(id), mapOfInfo[id]!!) }
}
batch.commit().addOnCompleteListener {
if (it.isSuccessful)
Grove.d { "Commit updated successfully" }
else Grove.d { "Commit fail" }
}
}
}