【问题标题】:(android firebase) determine reaching last item when paginating(android firebase)确定分页时到达最后一项
【发布时间】:2018-08-02 01:59:06
【问题描述】:

假设我在 Firebase 实时数据库中存储了 100 个项目(实际上它远远超过 100 个)。所以我决定使用分页,我使用 Query#addValueEventListener() 函数进行查询,每个请求只加载 20 个项目,最后一个查询项目的键传递给 Query#startAt() 以获取接下来的 20 个项目。到目前为止效果很好

但问题是,当我到达 Firebase 数据库中的最后一项(第 100 项)后,它会将数据库中的所有项(100 项)归还给我,以供下一个请求。 目前,我必须检查传递给 Query#startAt() 的密钥 id 和最后一个查询项目的密钥 id 是否相等,如果为真,那么我已经到达终点。老实说,我认为这不是一个很好的解决方案

所以这里的任何人都有更好的解决方案,请帮助我。 提前致谢!

这里的代码

private var lastKey: String? = null
fun requestItems(startAtId: String?){
    val query = dbRef.orderByKey()
    if(!startAtId.isNullOrBlank()){*the problem here*
        query.startAt(startAtId)
    }
    query.limitToFirst(10)
    query.addValueEventListener(object : ValueEventListener{
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            val lastKey = it.children.last().key
            if (lastKey.equals(startAtId)){
                //has reached the last item
                //ignore the result
            }else{
                //do something with the result
                lastKey = latestKey
            }
        }
        override fun onCancelled(dataSnapshot: DatabaseError) {

        }

    })

}

更新 我刚刚意识到我面临的问题是在 requestItems() 函数中初始化 Query 对象(第 1 行到第 5 行)。它总是从 db 返回整个项目。我将该初始化块更改为波纹管块。我不知道与他们有什么不同,但它起到了分页的作用。

val query = if(startAtId.isNullOrBlank()){
        dbRef.orderByKey()
    }else{
        dbRef.orderByKey()
                .startAt(startAtId)

    }.limitToFirst(10)

但是仍然没有迹象表明它到达了 db 中的最后一项。到达终点后 Firebase 总是返回最后一项,我认为这是因为 startAt(startAtId) 函数而发生的,并且没有像 startAtAfter(startAtId) 这样的函数

我附上了json file here,它不是数据库中的真实数据,但它们具有相同的结构。

【问题讨论】:

  • 如果将代码简化为单个查询,将硬编码值传递给startAt,您能否重现该问题?如果是这样,请更新您的问题以仅显示该代码。然后请对其进行编辑以包含重现它所需的最小 JSON(作为文本,请不要截图)。您可以通过单击 Firebase Database console 中的“导出 JSON”链接来获取此信息。
  • 嗨@FrankvanPuffelen 谢谢你的回答。我更新了我的问题

标签: android firebase firebase-realtime-database


【解决方案1】:

Firebase Query 对象是不可变的。每当您调用orderBystartAt 和其他方法之一时,它都会返回一个新的Query 对象。因此,您需要在变量中捕获该对象:

val query = dbRef.orderByKey()
if(!startAtId.isNullOrBlank()){
    query = query.startAt(startAtId)
}
query = query.limitToFirst(10)
...

这也是您更新的构造起作用的原因:您已将所有查询构建放入一个链中并捕获结果。但是虽然它有效,但我个人发现结果的可读性不如上面的。

【讨论】:

  • 感谢 Frank,这是一个有趣的信息。但是你知道如何在 db 中判断到达终点吗?
  • 如果你得到的结果比你请求的少,你就知道没有更多的结果了。
猜你喜欢
  • 2017-03-06
  • 1970-01-01
  • 2019-01-19
  • 1970-01-01
  • 1970-01-01
  • 2015-05-31
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多