【发布时间】:2019-11-27 16:27:32
【问题描述】:
考虑这个简单的 Firestore 数据库结构:
1:Firestore 结构
cities/
city1/
name:Beijing
likes: 0
dislikes: 0
... more fields
city2/
name: New York
likes: 21
dislikes: 1
... more fields
为了保护数据库免受意外操作,我添加了以下 Firestore 安全规则
2 Firestore 安全规则:
// Allow read/write access to all users under any conditions
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{cityId} {
allow read: if request.auth.uid != null;
allow update: if request.auth.uid != null &&
request.resource.data.keys().hasOnly(["likes", "dislikes"]);
}
}
}
这基本上允许我执行这些要求:
- 经过身份验证的用户可以读取城市数据。
- 经过身份验证的用户可以更新城市的“喜欢”和“不喜欢”字段。
问题
为什么上面的设置给了我一个Exception: PERMISSION_DENIED: Missing or insufficient permissions.,当我尝试使用批量写入,但如果我单独写入更改就成功了?
例如以下代码(使用 Batch 写入)失败:PERMISSION_DENIED: 权限缺失或不足。
fun rate(likes: List<String>, dislikes: List<String>, done: (Boolean) -> Unit) {
db.runBatch { batch ->
likes.map { cityCollection.document(it) }.forEach { doc ->
batch.update(doc,"likes", FieldValue.increment(1))
}
dislikes.map { cityCollection.document(it) }.forEach { doc ->
batch.update(doc,"dislikes", FieldValue.increment(1))
}
}.addOnCompleteListener { task ->
task.exception() // Exception: PERMISSION_DENIED: Missing or insufficient permissions.
done(task.isSuccessful) // false
}
}
而 没有批处理,代码可以正常工作。例如这完美无缺:
override fun rate(likes: List<String>, dislikes: List<String>, done: (Boolean) -> Unit) {
val tasks = likes.map { cityCollection.document(it) }.map { doc ->
doc.update("likes", FieldValue.increment(1))
}.union(dislikes.map { cityCollection.document(it) }.map { doc ->
doc.update("dislikes", FieldValue.increment(1))
})
Tasks.whenAllComplete(tasks).addOnCompleteListener { task ->
done(task.isSuccessful) // true
}
}
关于我的安全规则,我需要了解关于批量写入/事务的一些特殊情况吗?我希望这些更新以原子方式执行,因此我最初尝试使用批量写入。但是,我似乎无法让它们与我的安全规则结合使用。
【问题讨论】:
标签: android firebase google-cloud-firestore firebase-security