Ios 在Firebase中查询嵌套元素

Ios 在Firebase中查询嵌套元素,ios,swift,firebase,firebase-realtime-database,Ios,Swift,Firebase,Firebase Realtime Database,我正在尝试使用swift查询Firebase集合 我的收藏是这样的: { "networks" : { "-KF9zQYGA1r_JiFam8gd" : { "category" : "friends", "members" : { "facebook:10154023600052295" : true }, "name" : "My friends", "owner" : "facebook:1015402

我正在尝试使用swift查询Firebase集合

我的收藏是这样的:

{
  "networks" : {
    "-KF9zQYGA1r_JiFam8gd" : {
      "category" : "friends",
      "members" : {
        "facebook:10154023600052295" : true
      },
      "name" : "My friends",
      "owner" : "facebook:10154023600052295",
      "picture" : "https://my.img/img.png"
    },
    "-KF9zQYZX6p_ra34DTGh" : {
      "category" : "friends",
      "members" : {
        "tototata" : true
      },
      "name" : "My friends2",
      "owner" : "facebook:10154023600052295",
      "picture" : "https://my.img/img.png"
    }
  }
我的问题是:

let networksRef = ref.childByAppendingPath("networks")
                     .queryOrderedByChild("members")
                     .queryEqualToValue(true, childKey: uid)
然后,我使用FirebaseUI填充一个TableView

问题是查询不会返回任何内容,我也尝试使用这种查询:

let networksRef = ref.childByAppendingPath("networks")
                     .queryOrderedByChild("members")
                     .queryStartingAtValue(true, childKey: uid)
                     .queryEndingAtValue(true, childKey: uid)
需要明确的是,“uid”是嵌套在“members”节点中的节点名,值为true。(如图所示)

由于要下载的数据量很大,我无法在不进行筛选的情况下获取所有节点

我被这件事缠住了一天,我快发疯了…-)


如果有人能帮忙?

正确的语法是:

let networksRef = ref.childByAppendingPath("networks")
                     .queryOrderedByChild("members/\(uid)")
                     .queryEqualToValue(true)
但请注意,要使其高效工作,您需要为每个uid创建一个索引:

{
  "rules": {
    "networks": {
      ".indexOn": ["facebook:10154023600052295", "tototata"]
    }
  }
}
如果没有这些索引,Firebase客户端将下载所有数据并在本地进行筛选。结果是一样的,但会消耗大量不必要的带宽

一个合适的解决方案需要您改变数据结构。在Firebase(以及大多数其他NoSQL数据库)中,您通常以应用程序希望访问的方式对数据进行建模。由于您正在查找用户所属的网络,因此应按每个用户存储网络:

"networks_per_uid": {
  "facebook:10154023600052295": {
    "-KF9zQYGA1r_JiFam8gd": true
  },
  "tototata": {
    "-KF9zQYZX6p_ra34DTGh": true
  },
}

将这个所谓的索引添加到您的数据结构中被称为非规范化,并在和这篇伟大的文章中介绍。

正确的语法是:

let networksRef = ref.childByAppendingPath("networks")
                     .queryOrderedByChild("members/\(uid)")
                     .queryEqualToValue(true)
但请注意,要使其高效工作,您需要为每个uid创建一个索引:

{
  "rules": {
    "networks": {
      ".indexOn": ["facebook:10154023600052295", "tototata"]
    }
  }
}
如果没有这些索引,Firebase客户端将下载所有数据并在本地进行筛选。结果是一样的,但会消耗大量不必要的带宽

一个合适的解决方案需要您改变数据结构。在Firebase(以及大多数其他NoSQL数据库)中,您通常以应用程序希望访问的方式对数据进行建模。由于您正在查找用户所属的网络,因此应按每个用户存储网络:

"networks_per_uid": {
  "facebook:10154023600052295": {
    "-KF9zQYGA1r_JiFam8gd": true
  },
  "tototata": {
    "-KF9zQYZX6p_ra34DTGh": true
  },
}

将这个所谓的索引添加到您的数据结构中被称为非规范化,并在和这篇伟大的文章中介绍。

我刚刚根据要求更新了问题。清理了评论。我刚刚根据要求更新了问题。清理了评论。谢谢!不仅是为了答案,也是为了更好的方法!我将尝试以正确的方式重新排列所有数据@frank van puffelen-索引真的需要是“.indexOn”:[“facebook:10154023600052295”,“tototata”]还是“.indexOn”:[“成员”]会达到相同的结果?它需要位于您要搜索的属性上。您正在使用用户的UID搜索属性,因此您需要索引该属性。正如我的回答所解释的,这通常是由于使用了错误的数据结构来满足您的需要。有关详细解释,请参见“谢谢!”!不仅是为了答案,也是为了更好的方法!我将尝试以正确的方式重新排列所有数据@frank van puffelen-索引真的需要是“.indexOn”:[“facebook:10154023600052295”,“tototata”]还是“.indexOn”:[“成员”]会达到相同的结果?它需要位于您要搜索的属性上。您正在使用用户的UID搜索属性,因此您需要索引该属性。正如我的回答所解释的,这通常是由于使用了错误的数据结构来满足您的需要。有关详细说明,请参阅