flutter - 从 firebase 实时数据库获取数据切片,按喜欢降序排序以进行分页

flutter - get slices of data from firebase realtime database, sorted by descending likes for pagination

我在 firebase 实时数据库中有一份导师名单。而且他们每个人都有 'numFav' 表示有多少用户喜欢他。

在我的导师列表页面,我想按降序'numFav'的顺序显示已注册的导师。同时,我想分页

所以我编写了初始获取和加载更多代码。

  Future<List<MentorModel>> initialMentorFuture(int num) {
    final future = _database.orderByChild('numFav').limitToLast(num).once().then((snapshot) {
      List<MentorModel> _mentorList = [];
      Map<String, dynamic>.from(snapshot.value).forEach((key, value) => _mentorList.insert(0, MentorModel.fromRTDB(key, value)));
      return _mentorList;
    });

    return future;
  }

  Future<List<MentorModel>> moreMentorFuture(int num, int startAtValue) {
    final future = _database.orderByChild('numFav').startAt(startAtValue).limitToLast(num).once().then((snapshot) {
      List<MentorModel> _mentorList = [];
      Map<String, dynamic>.from(snapshot.value).forEach((key, value) => _mentorList.insert(0, MentorModel.fromRTDB(key, value)));
      return _mentorList;
    });

    return future;
  }

initialMentorFuture 按预期工作。 moreMentorFuture 没有。我有两个问题。

  1. 我使用的是降序,但是 limitToLast 和 startAt 似乎相互矛盾。

  2. 可以有很多导师具有相同的'numFav'。例如,如果第一页中的最后一位导师的 numFav 为 10,我不能只在 moreMentorFuture 中说 startAt(10) 因为可能还有其他导师的 numFav 为 10 而没有显示在第一页中。

我很确定我不是唯一一个尝试按喜欢的数量对列表进行排序的人。有人知道如何解决这个问题吗?

已编辑

还有一个问题:分页真的能节省加载时间吗?当我调用 .orderByChild('numFav').limitToLast(10) 时,实际从服务器下载了多少数据?如果我调用 orderByChild() 它会下载整个数据集进行排序吗?如果是这样,分页有什么意义?

Firebase 实时数据库始终returns 以升序排列结果。如果您想按降序显示它们,则需要在您的应用程序代码中反转结果。


如果你想要倒数第二页的结果,你需要使用 endAt 而不是 startAt:

_database.orderByChild('numFav').endAt(endAtValue, key: endAtKey).limitToLast(num)

如果不能保证您的 endAtValue 是唯一的(正如名称 numFav 所暗示的那样),您还需要保留 key要锚定的节点,以消除具有相同 numFav 值的节点之间的歧义。


Firebase 去年向实时数据库 API 添加了 startAfter/endBefore 方法,因此您可能需要考虑使用这些方法来排除 first/last 项next/previous 结果页。


对命名 属性(如 numFav)的查询要求您在规则中 define an index 才能在服务器上执行。在规则中定义索引后,查询将在服务器上执行。