如何在Firebase JSON树中表示双向关系? [英] How to represent a two ways relationship in a Firebase JSON tree?

查看:305
本文介绍了如何在Firebase JSON树中表示双向关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

警告:


  • 这个练习是为了更好地理解

    解决方案

    实际上有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

    every time I would query the child node "users" I would get all the users back

    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:

    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?

    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树中表示双向关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆