Android Firestore查询分页FirebaseFirestoreException:无效的\u参数
我有一个从firestore数据库获取帖子的函数,我正在跟踪文档,以便按最后一个索引文档对查询进行分页,但由于某种原因,在第一次获取后,当尝试运行下一个查询时,我收到Android Firestore查询分页FirebaseFirestoreException:无效的\u参数,android,firebase,kotlin,google-cloud-firestore,paging,Android,Firebase,Kotlin,Google Cloud Firestore,Paging,我有一个从firestore数据库获取帖子的函数,我正在跟踪文档,以便按最后一个索引文档对查询进行分页,但由于某种原因,在第一次获取后,当尝试运行下一个查询时,我收到com.google.firebase.firestore.FirebaseFirestoreException:无效的\u参数:Order by子句不能包含重复的字段上载时间戳 我还记录了日志,看到查询似乎正常,lastVisible在运行第一次查询后实际上是文档列表中的索引4,但不知何故,在第二次查询中,我又收到了所有前5篇帖子
com.google.firebase.firestore.FirebaseFirestoreException:无效的\u参数:Order by子句不能包含重复的字段上载时间戳
我还记录了日志,看到查询似乎正常,lastVisible
在运行第一次查询后实际上是文档列表中的索引4,但不知何故,在第二次查询中,我又收到了所有前5篇帖子
知道我做错了什么吗
suspend fun getMyPosts(userID: String): Flow<MutableList<DocumentSnapshot>> = flow {
Log.d(TAG, "getMyPosts() called -> userID is $userID")
var data: QuerySnapshot? = null
try {
data = dbRef.collection("posts")
.whereEqualTo("userID", userID)
.orderBy("uploadTimeStamp", Query.Direction.DESCENDING)
.limit(5)
.get()
.await()
Log.d(TAG, "emitting ${data.documents.size} posts: \n")
data.documents.forEach { doc ->
Log.d(
TAG,
"post number ${data.documents.indexOf(doc)}, timestamp: ${doc.get("uploadTimeStamp")}"
)
}
emit(data.documents)
while (!data!!.isEmpty && data.size() == 5) {
Log.d(TAG, "getting more posts")
val lastVisible = data.documents[data.size() - 1]
Log.d(TAG, "last index is ${data.size() - 1}")
Log.d(TAG, "lastVisible is ${lastVisible.get("uploadTimeStamp")}")
data = data.query
.whereEqualTo("userID", userID)
.orderBy("uploadTimeStamp", Query.Direction.DESCENDING)
.startAfter(lastVisible)
.limit(5)
.get()
.await()
if (!data.isEmpty) {
Log.d(TAG, "emitting ${data.documents}")
emit(data.documents)
}
}
} catch (e: Exception) {
Log.d(TAG, "Failed to get MyPosts,\n $e")
data!!.documents.forEach { doc ->
Log.d(
TAG,
"post number ${data.documents.indexOf(doc)}, timestamp: ${doc.get("uploadTimeStamp")}"
)
}
}
}
这是我的firestore文档结构
如果我们稍微简化您的代码,您将执行以下操作:
var data: QuerySnapshot? = null
try {
data = dbRef.collection("posts")
.whereEqualTo("userID", userID)
.orderBy("uploadTimeStamp", Query.Direction.DESCENDING)
.limit(5)
.get()
.await()
...
while (!data!!.isEmpty && data.size() == 5) {
val lastVisible = data.documents[data.size() - 1]
data = data.query
.whereEqualTo("userID", userID)
.orderBy("uploadTimeStamp", Query.Direction.DESCENDING)
.startAfter(lastVisible)
.limit(5)
.get()
.await()
因此,您通过再次调用whereEqualTo
和orderBy
来从原始值构建数据,这就是错误消息所抱怨的
最简单的修复方法是不重复使用数据的现有值,从而将data=data.query
更改为data=dbRef.collection(“posts”)
但您似乎正在尝试构建器模式,这实际上是一种更好的方法。在这种情况下,您需要确保不重建整个查询,而只添加与分页部分相关的子句:
data = data.query
.startAfter(lastVisible)
.get()
.await()
因此,这里我们只是添加了startAfter
子句,因为所有其他条件都已经存在于数据中。在您第一次构建它时查询它。请编辑您的问题并将您的数据库结构添加为屏幕截图。感谢您为我标记它,这真的很有帮助!。事实上,我的循环查询保存了第一个查询中的orderBy
和WhereEqualTo
,因此指出它是重复的,所以现在一切正常。我确实希望执行另一个data.query.startAfter(lastVisible)
会带来问题。顺便说一句,我通常会保留对“基本查询”的引用,即“除了startAt
/startAfter
”之外的所有内容,以便我可以将其用作分页的基础。
data = data.query
.startAfter(lastVisible)
.get()
.await()