问题描述
我有以下内容:
收藏集:
schedules
- uuid
- schoolUuid
- userUuid
- requestUuid
安全规则
match /schedules/{scheduleUuid}
function isAuthor(){
return resource.data.userUuid == request.auth.uid
}
function isAdmin(){
let schoolUuid = resource.data.schoolUuid
return get(/databases/$(database)/documents/admins/$(request.auth.uid)).data[schoolUuid] == true
}
read: if isAuth() && (isAuthor() || isAdmin())
create: if isAuth()
update: if isAuth() && (isAuthor() || isAdmin())
查询
作为管理员,此测试通过:
const db = firebaseDB({ uid: schoolAdmin.uuid,email: clinicAdmin.email });
const scheduleRef = db
.collection('schedules')
.where('schoolUuid','==','some-school-uuid');
await firebase.assertSucceeds(scheduleRef.get());
作为作者,该测试也通过了:
const db = firebaseDB({ uid: schoolEmployee.uuid,email: schoolEmployee.email });
const scheduleRef = db
.collection('schedules')
.where('userUuid','some-employeeUuid');
await firebase.assertSucceeds(scheduleRef.get());
现在,作为管理员或作者,以下查询失败:
const db = firebaseDB({ uid: schoolEmployee.uuid,email: schoolEmployee.email }); // either schoolEmployee or schoolAdmin
const scheduleRef = db
.collection('schedules')
.where('requestUuid','some-requestUuid');
await firebase.assertSucceeds(scheduleRef.get());
期望
我希望resource.data包含userUuid,schoolUuid,requestUuid。我注意到在“ where”查询中,resource.data上唯一可用的属性是我要查询的属性。例如,如果我这样做:
db.collection('schedules').where('schoolUuid','some-uuid')
在我的安全规则中,只有schoolUuid可用,如果我尝试访问userUuid或requestUuid,则会给出undefined。
当我专门查询文档时不是这种情况:
db.collections('schedules').doc('schedule-uuid')
在这种情况下,安全规则中的所有属性均可用。看来问题出在我执行where查询时。通过文档:
“查询约束与安全规则约束匹配”。我想知道它失败的原因是否是因为我没有'requestUuid','some-requestUuid'
我将不胜感激。看来我在这里误解了一些重要的东西。我一直在使用this reference
解决方法
当您在安全规则中使用resource
时,它指的是关闭或匹配的匹配集合中的特定文档。它没有引用任何父文档。如果需要参考规则明确匹配的文档之外的其他任何文档,则需要使用get()
,如accessing other documents的文档中所述。由于嵌套文档取决于其他文档的内容(即使它是父文档),因此它需要get()
。