【问题标题】:How to load next "n" items from the last item i load in firebase如何从我在firebase中加载的最后一个项目中加载下一个“n”个项目
【发布时间】:2018-01-09 02:30:46
【问题描述】:

我有数据,结构如下:

我想以无限滚动的形式加载来自用户的数据。所以我执行一个查询:

mGamersDatabaseReference.child(gameId).orderByChild("gamelvl").limitToFirst(10)

在此之前,我想加载接下来的 10 个项目。我已经尝试使用 startAt 并使用 userId 或用户名,但这不会加载更多项目。

 oldestPlayerGameLvl = myGames.getUserName();
mGamersDatabaseReference.child(gameId).orderByChild("gamelvl").limitToFirst(10).startAt(oldestPlayerGameLvl)

这不会加载任何东西,而且似乎startAt 方法仅在数字或字符串以给定字符串或数字开头而不是从子节点或节点 5 开始到子节点 10 时才有效。

//已编辑

我使用这种方法并且应该至少加载接下来的两个项目,或者我错了??

  mGamersDatabaseReference
  .child(gameId)
  .orderByChild("gamelvl")
  .startAt(0, "-L1Tg7NgZpT_7U4CiAs3") // i use this values
  .limitToFirst(10)

接下来是应该的方式,

 mGamersDatabaseReference
      .child(gameId)
      .orderByChild("gamelvl")
      .startAt(oldestPlayerGameLvl, oldestPlayerKey) 
      .limitToFirst(10)

其中 oldesPlayerGameLvl 等于最后一个节点中“gamelvl”的值,并且 oldPlayerKey 等于同一最后一个节点中的键的值。 但是这两种方法都返回 null。

//更新 https://github.com/QaplaGaming/QaplaG/blob/master/qapla.java

【问题讨论】:

    标签: java android firebase firebase-realtime-database infinite-scroll


    【解决方案1】:

    要加载下一页项目,你需要知道两件事:

    • 上一页最后一项的gamelvl的值。
    • 上一页最后一项的key,以防gamelvl有多个相同值的子节点。

    因此,如果您的屏幕截图中的最后一项是页面的最后一项,您将获得具有以下内容的下一页:

    mGamersDatabaseReference
      .child(gameId)
      .orderByChild("gamelvl")
      .startAt(0, "-L21rzBM...") // use the entire key
      .limitToFirst(10)
    

    【讨论】:

    • 实际上,这不起作用:/ 总是返回 null。查看 firebase 文档以使用 startAt 就像 ref.orderByChild("height").startAt(3) 并且这会加载从 3 开始的高度,例如 ....320,340 等。并且似乎不适用于数据内部某个点的负载。我尝试先使用密钥,然后再使用 0(或游戏 lvl),什么都没有。
    • 更新我们的问题以显示重现您尝试的内容和返回内容的最少代码。请继续阅读creating an MCVE,因为现在您的代码中有一些我们不知道它们是什么的东西(mGamersDatabaseReferencegameIdmyGames)。与其用文字描述它们是什么,不如尝试用硬编码值重现问题并分享。
    • 我不知道,我该如何修改来解释:/。我写的和你一样。我使用游戏等级的值和游戏等级的密钥。就是这样:/
    • 我必须使用部分密钥,您需要提供整个密钥:// use the entire key。我很确定我知道 API 是如何工作的,而且我也很确定你没有得到你期望的结果。现在有些东西在翻译中丢失了。解决这个问题的最好方法是providing an MCVE;特别是如果您在 jsbin 之类的网站上重现该问题,我们都可以看到相同的内容。
    • 我编辑了我的问题,希望你能理解。并衷心感谢您的宝贵时间。 :)
    【解决方案2】:

    编辑:虽然我的回答可能对 Swift 或 NodeJS 的用户有用,但我没有意识到实时数据库和 Firestore 的查询 API 并没有很好地跨平台统一。特别是,您可以在 NodeJS 中使用查询来完成在 Swift 中无法完成的事情,反之亦然。我想,Frank van Puffelen 上面的答案适用于 Android,我的解决方案在哪里......谁知道?

    结束编辑。剩下的留给后代。

    这很棘手,因为可能有很多人对 gameLvl 具有相同的值。我建议以下解决方案之一:

    1. 添加一个以某种方式将 gameLvl 和用户 ID 组合在一起的字段。例如,它可以是一个包含 gameLvl 的字符串(具有固定的位数,因此 42 可能是 00042),后跟一个连字符,然后是 userId。另一个例子:它可以是一个整数,等于 gameLvl 乘以十亿,加上 userId 以十亿为模的哈希值。然后按该字段排序,查询从您检索到的最后一个值开始。

    2. 切换到 Firestore,它类似于实时数据库,但大多更好。在查询中使用offset

    3. 切换到 Firestore。如果在第一个和第二个查询之间可能发生变化的列表上使用偏移量的想法让您感到不安,请在游戏级别和 userId 上定义一个索引。将您的查询设置为按 gameLvl 和 userId 排序。查询gameLvl == lastGameLvluserId > lastUserId 的位置,如果没有得到足够的结果,请在下一次查询gameLvl > lastGameLvl

    【讨论】:

    • 据我所知,Firestore 也不支持偏移量查询。事实上,实时数据库和 Cloud Firestore 之间的分页模型几乎没有变化:两者都使用锚项的概念。
    • 我的错误——显然这在 Firestore API 之间是不一致的。 nodejs 有偏移量:cloud.google.com/nodejs/docs/reference/firestore/0.8.x/… ...而 Swift 有 startAtDocument,这在这里更有用:firebase.google.com/docs/reference/swift/firebasefirestore/api/…
    • 我真的很震惊在任何地方都有offset()。我想知道如果您在集合的前面插入一个文档,而您的查询处于偏移位置,这个 API 是如何工作的。它应该会导致查询快照中的大量索引更新。想试一试并告诉我们结果吗?
    猜你喜欢
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2017-05-05
    • 2020-11-21
    • 2020-01-22
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    相关资源
    最近更新 更多