问题描述
警告:
实际上有5个不同的问题。
根节点是:myparentnodename
您的用户
用户
uid_0
名称:William
door_keys:
key_0:true
key_3:true
uid_2
name:Leonard
door_keys:
key_3:true
key_5:true
和您的钥匙
钥匙
钥匙_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
您的问题是
lockquote $ b $每次我会查询子节点用户我会得到所有的
用户回来
这是稍微不完整。查询完成后,您通常会查询特定的内容。然而,使用Firebase有两种方式来检索数据:观察一个节点和一个查询。
如果您想要备份用户节点中的所有用户,您可以观察到该节点(或.ChildAdded一次1)。
ref = myParentNodeName
let usersRef = myParentNodeName.childByAppendingPath (users)
usersRef.observeEventType(.Value,withBlock:{snapshot in
//.Value可以返回快照中的多个节点,以便迭代它们
$ snapshot.children {
let name = child.value.objectForKey(name)as!String
print(name)//打印每个用户名
} $ b请注意,上面附加了一个观察者的用户节点,所以任何未来的变化节点将通知应用程序并重新发送整个节点到应用程序
如果您只需要一个用户的信息,并且不想继续观察更改
p>
ref = myParentNodeName
let usersRef = myParentNodeName.childByAppendingPath(users)
let thisUserRef = usersRef.childByAppendingPath(uid_2)
thisUserRef.observeSingleEventOfType(.Value,withBlock: {快照
让name = child.value.objectForKey(name)as!字符串
print(name)//输出每个用户名称
})
最后,查询属于uid_0的所有密钥(在这个例子中有点冗余,因为我们已经知道它们的节点有哪些密钥)。如果钥匙中还包含其他信息,例如门名称,门所在的建筑物或门的位置,则会更合适,并且需要不同的结构,所以假设情况如下:
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)//打印每个用户的名字
})
另外一个问题:
lockquote
我们可以做嵌套查询吗?例如将以前的条件与
门钥匙上的一些条件结合起来,这样返回的JSON对象只与$ user
lockquote>
我认为你的意思是你可以查询uid_2,看看他们有哪些键,然后加载这些特定键的信息。
是的!但是...(总有一个但是)
Firebase是异步的,所以在嵌套查询时你必须考虑到这一点,也就是说你需要确保所有的数据都被返回在获得更多数据之前。因此,例如,如果您想要uid_2关键数据,则可以在节点uid_2上观察到SingleEventOfType。然后您将拥有自己的密钥,然后可以在每个密钥上观察SingleEventOfType。从技术上讲,这可以工作,但是随着异步数据的飞行,你可能会在代码在其他代码上跺脚,并且在实际返回数据之前处理数据。$ / $> b
$ b
更好的选择(按照我的例子)就是完全避免这个问题,并且查询uid_2的键的键节点。
作为注意,观察一个节点的开销比查询要少很多,所以如果你想加载一个节点并且知道路径,可以使用observe。
Warning:
- this is an exercise to understand better JSON database design in Firebase
- it is not necessarily realistic
I have got a two ways relationship between users and door keys. I would like to understand:
- how to represent this relationship visually (I can imagine it only as two separate trees)
- how this would work on Firebase, would both users and door-keys be child of a parent node "myparentnodename"?
- If I model the database in this way it feels highly inefficient because every time I would query the child node "users" I would get all the users back. Or am I wrong? Is it possible to only get back the data matching to a specific user? E.g. get user where "user = user1"? Can we do nested queries? e.g. combine the previous condition with some condition on the door keys so the JSON object returned is only relevant to the door-keys contained in the "user1" node?
解决方案 This is a very long answer as your question was actually about 5 different questions.
root node is: myparentnodename
Your users
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
and your keys
keys
key_0
uid_0: true
key_3
uid_0: true
uid_2: true
key_5
uid_5: true
With this structure, all of the elements 'point' at each other.
If you query uid_0 you can see that they use keys 0 and 3
If you query key_3 you can see they belong to users 0 and 2
Your question was
That's slightly incomplete. When a query is done, you usually query for something specific. With Firebase however, there are two ways to retrieve data: observing a node and a query.
If you want back all users in the users node you would observe that node by .Value (or .ChildAdded for 1 at a time).
ref = myParentNodeName
let usersRef = myParentNodeName.childByAppendingPath("users")
usersRef.observeEventType(.Value, withBlock: { snapshot in
//.Value can return multiple nodes within the snapshot so iterate over them
for child in snapshot.children {
let name = child.value.objectForKey("name") as! String
print(name) //prints each users name
}
})
note that the above attaches an observer to the users node so any future changes within that node will notify the app and re-send the entire node to the app
If you want just one user's info, and don't want to continue watching for changes
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) //prints each users name
})
Finally, to query for all keys that belong to uid_0 (which is a little redundant in this example since we already know which keys they have from their node). If the keys ref also contained other info like the door name, the building the door was in, or the door location, it would be more appropriate and would require a different structure, so assume that's the case:
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) //prints each users name
})
note this code is Swift since the platform was not specified in the question.
The other question:
I think you mean can you query for uid_2, see which keys they have and then load in the info from those specific keys.
Yes! But... (there's always a but)
Firebase is asynchronous so you have to take that into account when nesting queries i.e. you need to ensure all of the data is returned before getting more data. So for example, if you wanted uid_2 key data, you could observeSingleEventOfType on node uid_2. You would then have their keys and could then observeSingleEventOfType on each key.
Technically this will work but with asynchronous data flying around, you could end up with code stomping on other code and processing data before it's actually been returned.
The better option (per my example) is to just avoid that entirely and query the keys node for uid_2's keys.
As a side note, observing a node has a lot less overhead than a query so if you want to load a single node and you know the path, use observe.
这篇关于如何在Firebase JSON树中表示双向关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!