如何从我在 firebase 中加载的最后一项加载下一个 "n" 项
How to load next "n" items from the last item i load in firebase
我有数据,结构如下:
我想加载来自用户的数据作为无限卷轴。所以我执行查询:
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" 的值,并且
oldestPlayerKey 等于最后一个节点中的键值。
但是这两种方法 returns null.
//更新
https://github.com/QaplaGaming/QaplaG/blob/master/qapla.java
编辑: 虽然我的回答可能对 Swift 或 NodeJS 的用户有用,但我没有意识到实时数据库和 Firestore 的查询 API 是'跨平台统一。特别是,您可以在 NodeJS 中使用查询来完成在 Swift 中无法完成的事情,反之亦然。我认为 Frank van Puffelen 上面的回答适用于 Android,我的解决方案...谁知道?
结束编辑。剩下的留给子孙后代。
这很棘手,因为可能有很多人的 gameLvl 值相同。我建议采用以下解决方案之一:
添加一个以某种方式组合 gameLvl 和用户 ID 的字段。例如,它可以是一个包含 gameLvl 的字符串(具有固定位数,因此 42 可以是 00042),后跟一个连字符,然后是 userId。另一个例子:它可以是一个等于 gameLvl 乘以十亿的整数,加上 userId 以十亿为模的散列。然后按该字段排序,您的查询从您检索到的最后一个值开始。
切换到 Firestore,它类似于实时数据库,但大多更好。在查询中使用 offset
。
切换到 Firestore。如果在列表上使用偏移量的想法可能会在您的第一个和第二个查询之间发生变化,这让您感到厌烦,请在游戏级别和 userId 上定义一个索引。将您的查询设置为按 gameLvl 排序,然后按 userId 排序。在 gameLvl == lastGameLvl
和 userId > lastUserId
处进行查询,如果没有获得足够的结果,请进行下一次查询 gameLvl > lastGameLvl
.
要加载下一页项目,您需要了解两件事:
- 上一页最后一项的
gamelvl
的值。
- 上一页最后一项的key,以防子节点有多个相同的值
gamelvl
。
因此,如果屏幕截图中的最后一项是页面的最后一项,您将获得下一页:
mGamersDatabaseReference
.child(gameId)
.orderByChild("gamelvl")
.startAt(0, "-L21rzBM...") // use the entire key
.limitToFirst(10)
我有数据,结构如下:
我想加载来自用户的数据作为无限卷轴。所以我执行查询:
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" 的值,并且 oldestPlayerKey 等于最后一个节点中的键值。 但是这两种方法 returns null.
//更新 https://github.com/QaplaGaming/QaplaG/blob/master/qapla.java
编辑: 虽然我的回答可能对 Swift 或 NodeJS 的用户有用,但我没有意识到实时数据库和 Firestore 的查询 API 是'跨平台统一。特别是,您可以在 NodeJS 中使用查询来完成在 Swift 中无法完成的事情,反之亦然。我认为 Frank van Puffelen 上面的回答适用于 Android,我的解决方案...谁知道?
结束编辑。剩下的留给子孙后代。
这很棘手,因为可能有很多人的 gameLvl 值相同。我建议采用以下解决方案之一:
添加一个以某种方式组合 gameLvl 和用户 ID 的字段。例如,它可以是一个包含 gameLvl 的字符串(具有固定位数,因此 42 可以是 00042),后跟一个连字符,然后是 userId。另一个例子:它可以是一个等于 gameLvl 乘以十亿的整数,加上 userId 以十亿为模的散列。然后按该字段排序,您的查询从您检索到的最后一个值开始。
切换到 Firestore,它类似于实时数据库,但大多更好。在查询中使用
offset
。切换到 Firestore。如果在列表上使用偏移量的想法可能会在您的第一个和第二个查询之间发生变化,这让您感到厌烦,请在游戏级别和 userId 上定义一个索引。将您的查询设置为按 gameLvl 排序,然后按 userId 排序。在
gameLvl == lastGameLvl
和userId > lastUserId
处进行查询,如果没有获得足够的结果,请进行下一次查询gameLvl > lastGameLvl
.
要加载下一页项目,您需要了解两件事:
- 上一页最后一项的
gamelvl
的值。 - 上一页最后一项的key,以防子节点有多个相同的值
gamelvl
。
因此,如果屏幕截图中的最后一项是页面的最后一项,您将获得下一页:
mGamersDatabaseReference
.child(gameId)
.orderByChild("gamelvl")
.startAt(0, "-L21rzBM...") // use the entire key
.limitToFirst(10)