我最近一直在开发一个应用程序,偶然遇到了另一个问题(这就是程序员的生活,不是吗?)。郑重声明,我使用的是最新版本的Swift、XCode和Firebase。我只想获取父级的直系后代(我的引用)。这是我的JSON树:
users
family-name
user-1 // I want this...
pass: abc // but not this ...
user-2 // ... and this
pass: def // ... but not this
events // I skip this specifically in my code
event-1
a: a
b: b
event-2
a: a
b: b
event-3
a: a
b: b如树中所示,我只想获取user-1、user-2和user-3。
我尝试使用一个普通的查询,但它并没有起作用,我不仅得到了我想要的查询,还得到了子值。
let query = userRef.queryOrdered(byChild: "users")
query.observe(.value, with: { (snapshot) in
for child in snapshot.children {
let value = snapshot.value as? NSDictionary
for anotherChild in value! {
if "\(key)" == "events" {
print("Let's skip that, since it's just the events sub-tree!")
} else {
// my work goes here
}我得到了六个返回的值,但我希望返回两个。我不知道为什么!提前感谢任何能帮上忙的人。
发布于 2019-07-26 22:38:16
我将提供一个具体的答案,这个问题和一个建议的结构变化与答案。
首先,当以任何方式读取Firebase节点时,它将随子数据一起加载节点键(这是您想要的)。这就是Firebase的工作方式。只要子数据不是很广泛,那么它就非常简单。
在这里,我们加载users系列节点,该节点加载系列中的所有数据,然后将子快照数据分配给字典,它们是键:值对。从那里开始,我们创建一个包含这些键(user-1、user-2等)的数组,然后迭代它们,打印所有不是“event”的键。
func printUids() {
let familyRef = self.ref.child("users").child("family-name")
familyRef.observeSingleEvent(of: .value, with: { snapshot in
let dict = snapshot.value as! [String: Any]
let allKeys = dict.keys
for key in allKeys {
if key != "events" {
print(key)
}
}
})
}然而,在这些情况下,反规范化数据可能会导致加载的数据丢失较少。我不知道确切的用例,但让我介绍一个修改后的结构,其中所有用户都存储在一个users节点中,然后家庭数据存储在另一个节点中。
users
uid_0
name: "uid_0 users name"
fav_food: "pizza"
uid_1
name: "uid_1 users name"
fav_food: "pizza"然后是家族数据,其中包含家族名称、该家族的事件以及属于该家族的家族成员(用户),由用户uid引用
families
family_id_0
family_name = "some family name"
family_users
uid_0: true
uid_1: true
family_events
event_0
event_desc: "family reunion"
event_data: "some date"假设我们想知道哪些家庭成员(用户)属于family_id_0。下面的代码读取族的特定节点,并打印族成员(用户)
func printFamilyUsers() {
let familiesRef = self.ref.child("families")
let whichFamilyRef = familiesRef.child("family_id_0")
let familyUsersRef = whichFamilyRef.child("family_users")
familyUsersRef.observeSingleEvent(of: .value, with: { snapshot in
let theUsers = snapshot.children.allObjects as! [DataSnapshot]
theUsers.forEach { print($0.key) }
})
}这里的优点是用户是通过引用来存储的,所以在加载用户时,只需要很少的数据量;只需要一个uid和一个bool。
如果需要,我可以进一步更新。
发布于 2019-07-26 08:10:55
实时数据库查询是“深度”的,因为对节点的请求总是重试该节点下的所有子节点。在使用客户端库时,没有“浅层”查询,也没有办法从节点中排除子节点。如果你想要特定的孩子,而不是他们的兄弟姐妹,你必须逐个请求他们。
https://stackoverflow.com/questions/57211458
复制相似问题