我正在尝试创建一个
最佳方法是保留路径(在本例中为
我使用
但即使以这种方式执行,我仍然会收到错误消息,
以下是我的方法:
WriteBatch
,来控制我的数据库中动态引用之一。我的应用程序具有简单的User-Follow-Post-Feed
模型,我希望用户在其Feed中看到他关注的所有用户的帖子。通过Firebase示例(如Firefeed)和Stack Overflow上的许多帖子研究后,我做了以下操作。最佳方法是保留路径(在本例中为
collection
),其中存储用户应在其Feed中看到的帖子的Ids
。这意味着需要控制关注/取消关注的所有用户的每篇帖子的复制和删除。我使用
Cloud functions
以原子方式保持此状态,并且一切正常运行。但是,当我尝试进行大规模测试时,向用户添加超过5000个帖子并试图关注他(寻找查看Cloud function
将花费多长时间),我发现batch有500个操作的限制。因此,我将我的5000个ID拆分为多个小列表,并为每个列表执行一个batch,从未超过500个限制。但即使以这种方式执行,我仍然会收到错误消息,
我无法在单个提交中执行超过500个操作
,我不知道是否因为批次同时执行,或者其他原因。我认为也许可以将它们连接在一起,并避免同时执行它们。但我仍然遇到了一些问题,这就是我的问题所在。以下是我的方法:
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" }
}
}
}