作为你的问题涉及5个不同问题,因此我的回答非常长。
根节点是:myparentnodename
您的用户
users
uid_0
name: "William"
door_keys:
key_0: true
key_3: true
uid_2
name: "Leonard"
door_keys:
key_3: true
key_5: true
和你的密钥
keys
key_0
uid_0: true
key_3
uid_0: true
uid_2: true
key_5
uid_5: true
使用这种结构,所有元素都会“指向”彼此。
如果您查询uid_0,可以看到它们使用键0和3
如果您查询key_3,可以看到它们属于用户0和2
您的问题是:
每次查询子节点“users”时,我都会得到所有用户的返回
这有点不完整。当进行查询时,通常会查询特定内容。然而,在Firebase中,检索数据有两种方式:观察节点和查询。
如果您想获取users节点中的所有用户,请通过.Value(或.ChildAdded逐个)观察该节点。
ref = myParentNodeName
let usersRef = myParentNodeName.childByAppendingPath("users")
usersRef.observeEventType(.Value, withBlock: { snapshot in
for child in snapshot.children {
let name = child.value.objectForKey("name") as! String
print(name)
}
})
请注意,以上代码将观察者附加到用户节点,因此该节点内的任何未来更改都将通知应用程序并将整个节点重新发送到应用程序。
如果您只想获取一个用户的信息,并且不想继续观察更改,请使用以下代码:
ref = myParentNodeName
let usersRef = myParentNodeName.childByAppendingPath("users")
let thisUserRef = usersRef.childByAppendingPath("uid_2")
thisUserRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
let name = child.value.objectForKey("name") as! String
print(name)
})
最后,为了查询属于uid_0的所有键(在这个示例中有点冗余,因为我们已经知道它们的节点拥有哪些键)。如果键的ref还包含其他信息,比如门名称、门所在的建筑物或门的位置,那么采用不同的结构会更加合适,因此请假设是这种情况:
ref = myParentNodeName
let keysRef = myParentNodeName.childByAppendingPath("keys")
keysRef.queryOrderedByChild("uid_0").queryEqualToValue(true)
.observeSingleEventOfType(.Value, withBlock: { snapshot in
let doorLocation = child.value.objectForKey("door_location") as! String
print(doorLocation)
})
请注意,由于问题中没有指定平台,因此此代码为Swift。
另一个问题:
我们可以进行嵌套查询吗?例如,将先前的条件与某些关于门钥匙的条件相结合,以便返回的JSON对象仅与包含在“user1”节点中的门钥匙相关?
我认为您的意思是可以查询uid_2,查看他们拥有哪些键,然后从这些特定的键加载信息。
是的!但是...(总有一个但是)
Firebase是异步的,因此在嵌套查询时必须考虑到这一点,即您需要确保在获取更多数据之前返回所有数据。因此,例如,如果您想要uid_2密钥数据,则可以在uid_2节点上观察SingleEventOfType。然后,您将拥有他们的密钥,然后可以在每个密钥上观察SingleEventOfType。
从技术上讲,这将起作用,但是由于异步数据四处飞行,您可能会遇到代码践踏其他代码并在实际返回之前处理数据的情况。
更好的选择(根据我的示例)是完全避免这种情况,并查询uid_2的密钥节点。
顺便说一下,观察节点比查询的开销要小得多,因此如果要加载单个节点并且您知道路径,请使用observe。