Firebase:在 swift 中将过滤与排序相结合

Firebase: combine filtering with ordering in swift

所以我有一个体育应用程序,可以处理比赛和锦标赛数据。 我有两个显示器使用相同的数据:

数据结构如下

- championships
    - libertadores
        - name: Libertadores da América
- matches
    - 2j6g42kjhg62
        - champ: libertadores
        - time: 1433962855
        - <data> //teams, scores, stadium and so on

现在,显示未来的比赛很容易:

matchesRef.queryOrderedByChild("time").queryStartingAtValue(currentTimestamp)
            .queryLimitedToFirst(20)
            .observeEventType(.ChildAdded, withBlock: { (snapshot) in
                // code
            })

但是,因为您不能使用多个 queryOrderedByChild,所以我坚持将其与锦标赛过滤相结合。

我考虑过更改我的数据结构以支持类似 /championship/matches/<matchID> 的内容,但这会让我很难显示所有未来的匹配项。

不过滤不是这里的选项,那么我怎样才能达到预期的结果?

知道了!

我在发布问题之前已经阅读了文档,但还没有点击引导我找到解决方案。

关于结构化数据的这一部分包含答案:https://www.firebase.com/docs/ios/guide/structuring-data.html

了解: 自然结构是:

 - champs
    - champID
        - matches
            - matchID
            - <matchData>
        - champName

但是,要使用 firebase,我们需要规范化数据:

- champs
    - champID
        - champName

- matches
    - matchID
        - champID
        - timestamp
        - <matchData>

我开始提问的结构是什么。

但是,由于锦标赛有比赛,比赛属于锦标赛,因此我们需要将两者相互参照。上面链接的文档告诉我们可以给键一个值 true 因为我们对键的值不感兴趣,只知道它存在。但是,由于我只需要未来的比赛,解决方案是将比赛时间戳放在值中。

- champs
    - champID
        - matches
            - matchID: timestamp
        - champName
- matches
    - matchID
        - champID
        - timestamp
        - <matchdata>

现在是最终代码:

未过滤的视图:

// Query non-filtered matches Reference
matchesRef.queryOrderedByChild("time").queryStartingAtValue(currentTimestamp)
    .queryLimitedToFirst(20).observeEventType(.ChildAdded, withBlock: { (snapshot) in
            // code
    })

筛选视图:

// Query filtered matches
champsRef.childByAppendingPath(champKey).childByAppendingPath("matches")
    .queryOrderedByValue().queryStartingAtValue(currentTimestamp)
    .queryLimitedToFirst(20)
    .observeEventType(.ChildAdded, withBlock: { (snapshot) in
        let key = snapshot.key
        matchesRef.childByAppendingPath(key).observeSingleEventOfType(.Value, withBlock: { (matchSnapshot) in
            // code
        })
    })

在 firebase 中,您只能根据 queryOrderedBy(child: String) 键进行过滤。在我的例子中,我需要过滤多个日期范围(每个日期范围都是 UITableView 中的一个部分),并在这些日期范围内在一个单独的字段上排序。解决方案是使用 FUISortedArray,它采用 sortDescriptor (DataSnapshot, DataSnapshot) -> ComparisonResult