Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 观察到SingleEvent时,Swift Firebase规则权限被拒绝_Ios_Swift_Firebase_Firebase Realtime Database_Firebase Security - Fatal编程技术网

Ios 观察到SingleEvent时,Swift 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) ||

我正在开发一个应用程序,允许教师记录学生的课程。使用Firebase规则,我希望允许教师进入某些学校。我有以下规则:

{
  "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,然后加载每个学校。这种加载比大多数开发人员预期的要快得多,因为


    有关此方法的详细说明,请参见和。

    Is
    DataService.ds.REF\u SCHOOLS
    指向
    SCHOOLS
    School/Some\u School\u ID
    ?指向Database.Database().reference().child(“学校”)