Ios 观察到SingleEvent时,Swift Firebase规则权限被拒绝
我正在开发一个应用程序,允许教师记录学生的课程。使用Firebase规则,我希望允许教师进入某些学校。我有以下规则:Ios 观察到SingleEvent时,Swift Firebase规则权限被拒绝,ios,swift,firebase,firebase-realtime-database,firebase-security,Ios,Swift,Firebase,Firebase Realtime Database,Firebase Security,我正在开发一个应用程序,允许教师记录学生的课程。使用Firebase规则,我希望允许教师进入某些学校。我有以下规则: { "rules": { "Schools" : { "$schoolId" : { ".read" : "data.child('Teachers').hasChild(auth.uid)", ".write" : "data.child('Teachers').hasChild(auth.uid) ||
{
"rules": {
"Schools" : {
"$schoolId" : {
".read" : "data.child('Teachers').hasChild(auth.uid)",
".write" : "data.child('Teachers').hasChild(auth.uid) ||
root.child('User').child(auth.uid).child('Invitation').exists()"
}
},
"Users" : {
"$uid" : {
".read" : "auth.uid === $uid",
".write": "auth.uid === $uid"
}
}
}
}
在模拟器中,一切正常,但当触发以下命令时,所有学校都被拒绝所有权限
DataService.ds.REF_SCHOOLS.observeSingleEvent(of: .value) { (snapshot) in
MySchools.mySchoolKeyList.removeAll()
MySchools.mySchoolList.removeAll()
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
for snap in snapshot {
if let recordDict = snap.value as? Dictionary<String, AnyObject> {
if let name = (recordDict["SchoolName"] as? String) {
MySchools.mySchoolList.append(name)
}
MySchools.mySchoolKeyList.append(snap.key)
}
}
if MySchools.mySchoolList.isEmpty {
MySchools.mySchoolList.append("You do not belong to any schools.")
}
}
}
DataService.ds.REF_.observeSingleEvent(of:.值){(快照)位于
MySchools.mySchoolKeyList.removeAll()
MySchools.mySchoolList.removeAll()
如果让snapshot=snapshot.children.allObjects为?[DataSnapshot]{
用于管理单元快照{
如果让recordDict=snap.value作为字典{
如果let name=(recordDict[“school name”]作为?字符串){
MySchools.mySchoolList.append(名称)
}
MySchools.mySchoolKeyList.append(snap.key)
}
}
如果MySchools.mySchoolList.isEmpty{
MySchools.mySchoolList.append(“您不属于任何学校。”)
}
}
}
以下是Firebase数据库的快照,以供参考:
有人知道我的规则出了什么问题吗?此外,如何处理拒绝许可的结果也将不胜感激 您的代码正在尝试从
/Schools
读取,但您的规则不允许任何人从/Schools
读取。因此Firebase正确地拒绝读取
我感觉您希望读取操作自动过滤结果,只返回用户有权访问的学校节点(/Schools/$schoolId
)。但这不是Firebase安全规则的工作方式:
这是开发人员在开始使用Firebase的服务器端安全规则时常见的困惑,所以我建议您查看以前的一些
现在有一种方法可以获得过滤后的数据,而不需要用户访问所有
学校。为此,您需要:
使用查询仅请求您应该可以访问的学校
验证安全规则中的/Schools
是否允许此查询
有关此示例,请参见文档中的
代码应该是这样的:
let query = DataService.ds.REF_SCHOOLS.queryOrdered(byChild: "Teachers/"+uid).queryValue(equalTo: true);
query.observeSingleEvent(of: .value) { (snapshot) in
...
但问题是你需要为每个老师定义一个索引。虽然这在技术上是可能的,但会导致索引数量不合理
事后来看:您当前的数据结构允许您高效地找到特定学校的教师。但是,它不允许您高效地为特定教师找到学校
为了有效地查找特定教师的学校,请向数据库中添加一个额外的数据结构,将学校映射到每个教师。例如
teacherSchools
teacherUid1
schoolId1: true
schoolId2: true
teacherUid2
schoolId2: true
schoolId3: true
使用此结构,您可以轻松读取教师的所有学校ID,然后加载每个学校。这种加载比大多数开发人员预期的要快得多,因为
有关此方法的详细说明,请参见和。IsDataService.ds.REF\u SCHOOLS
指向SCHOOLS
或School/Some\u School\u ID
?指向Database.Database().reference().child(“学校”)