如何在 Firebase JSON 树中表示两种方式的关系? [英] How to represent a two ways relationship in a Firebase JSON tree?

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

问题描述

警告:

  • 这是一个练习,可以更好地理解

    解决方案

    这是一个很长的答案,因为您的问题实际上是关于 5 个不同的问题.

    根节点是:myparentnodename

    您的用户

     用户uid_0名称:威廉"门钥匙:key_0: 真key_3: 真uid_2名称:伦纳德"门钥匙:key_3: 真key_5: 真

    还有你的钥匙

     键key_0uid_0:真key_3uid_0:真uid_2:真key_5uid_5:真

    使用这种结构,所有元素都指向"彼此.

    如果您查询 uid_0,您可以看到他们使用键 0 和 3

    如果您查询 key_3,您可以看到它们属于用户 0 和 2

    你的问题是

    <块引用>

    每次我查询子节点用户"时,我都会得到所有用户返回

    这有点不完整.完成查询后,您通常会查询特定的内容.然而,使用 Firebase,有两种方法可以检索数据:观察节点和查询.

    如果您想要返回 users 节点中的所有用户,您可以通过 .Value(或 .ChildAdded 一次 1)观察该节点.

    ref = myParentNodeName让 usersRef = myParentNodeName.childByAppendingPath("users")usersRef.observeEventType(.Value, withBlock: { 中的快照//.Value 可以在快照中返回多个节点,因此可以遍历它们对于快照中的孩子.孩子{让 name = child.value.objectForKey("name") as!细绳print(name)//打印每个用户的名字}})

    请注意,上面将观察者附加到用户节点,因此该节点内的任何未来更改都会通知应用程序并将整个节点重新发送到应用程序

    如果您只需要一个用户的信息,并且不想继续关注变化

    ref = myParentNodeName让 usersRef = myParentNodeName.childByAppendingPath("users")让 thisUserRef = usersRef.childByAppendingPath("uid_2")thisUserRef.observeSingleEventOfType(.Value, withBlock: { 中的快照让 name = child.value.objectForKey("name") as!细绳print(name)//打印每个用户的名字})

    最后,查询属于 uid_0 的所有键(这在本例中有点多余,因为我们已经知道它们从其节点获得了哪些键).如果键 ref 还包含其他信息,例如门名称、门所在的建筑物或门的位置,则它会更合适,并且需要不同的结构,因此假设是这种情况:

    ref = myParentNodeName让 keysRef = myParentNodeName.childByAppendingPath("keys")keysRef.queryOrderedByChild("uid_0").queryEqualToValue(true).observeSingleEventOfType(.Value, withBlock: { 中的快照让 doorLocation = child.value.objectForKey("door_location") 为!细绳print(doorLocation)//打印每个用户名})

    请注意此代码是 Swift,因为问题中未指定平台.

    另一个问题:

    <块引用>

    我们可以进行嵌套查询吗?例如结合前面的条件门钥匙上的某些条件,因此返回的 JSON 对象仅与user1"节点中包含的门钥匙相关吗?

    我认为您的意思是您可以查询 uid_2,查看它们有哪些键,然后从这些特定键中加载信息.

    是的!但是...(总有一个但是)

    Firebase 是异步的,因此您在嵌套查询时必须考虑到这一点,即您需要确保在获取更多数据之前返回所有数据.因此,例如,如果您想要 uid_2 关键数据,您可以在节点 uid_2 上观察SingleEventOfType.然后,您将拥有他们的键,然后可以在每个键上观察SingleEventOfType.

    从技术上讲,这是可行的,但在异步数据四处飞散的情况下,您最终可能会在数据实际返回之前将代码踩在其他代码上并处理数据.

    更好的选择(根据我的示例)是完全避免这种情况,并在键节点中查询 uid_2 的键.

    附带说明,观察节点的开销比查询要少得多,因此如果您想加载单个节点并且知道路径,请使用观察.

    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天全站免登陆