Firebase - 根据(大)孩子

时间:2017-07-01 11:52:38

标签: java firebase firebase-realtime-database

我有这样的数据路径

events
    -KntTJCVBtbrb79dHemC
        dateStamp: 1498747689858
        admin: "rPxwIzEtJaRbEH6ujkP5QJgpHDp2"
        attending:
            rPxwIzEtJaRbEH6ujkP5QJgpHDp2: true
            MtaPwHEKMEOTXBRdXBuXuS3gst12: false

我想获得某些用户参加的活动。换句话说,我想获取“参加/ [some-user-id]”键存在的所有事件

问题是我只能通过过滤该路径的特定值(true或false)来实现,如下所示:

eventsRef.orderByChild("attending/" + user.getId()).equalTo(true).addListenerForSingleValueEvent(...)

只有在键的值为真的情况下才有效,所以为了得到我需要的东西,我必须做2次调用,一次是值,一次是值,一次是假值。

我尝试使用 startAt(true) endAt(false)(反之亦然)但最终没有返回任何内容。

我不确定我错过了什么。

修改

我应该指明我知道这可以通过非规范化并使用另一个节点作为关系'table'来完成,我只是想知道上面的具体是否可行,因为它已经如此接近并且它将避免2-首先获取密钥然后检索实际数据的步骤。

1 个答案:

答案 0 :(得分:2)

在数据非规范化发挥作用的时候!

您所描述的是查询孙子的唯一方法。当然,正如您所提到的,它不是非常直观,有用或快速。

您需要做的是为参加特定活动的用户创建单独的节点。您可以将其命名为UsersAttendingTheEvent。这将把事件键作为子项。每当用户开始参加给定事件时,将用户密钥添加为事件密钥的子项(因此,UsersAttendingTheEvent的孙子。

所以,例如,

UsersAttendingTheEvent:{
 -KntTJCVBtbrb79dHemC:{
        rPxwIzEtJaRbEH6ujkP5QJgpHDp2: true
        MtaPwHEKMEOTXBRdXBuXuS3gst12: false
       }}

现在,当您想要运行查询时,您可以在orderByChild(userId)上运行简单的UsersAttendingTheEvent查询,以获取用户正在参与的事件的所有键。

在此之后,您可以从主event/eventKey获取活动详情。这似乎是一个额外的调用,但它是如何为Firebase设计数据的非规范化。此外,它的工作速度也相当快。

修改

您的startAt(true)和endAt(false)没有返回任何内容的原因是,当调用orderByChild()时,返回项目的顺序如下: -

  1. 数值
  2. 字典顺序
  3. 此页面上提到https://firebase.google.com/docs/database/android/lists-of-data

    请尝试仅使用startAt(true)。如果您确保您的成员键只有true或false值,并且在true之后没有按字典顺序返回其他值,这将有效。