Android Firestore分页查询报INVALID_ARGUMENT: uploadTimeStamp排序字段重复错误
问题根源
- 你在构造下一页查询时,调用的
data.query对象本身已经包含了首次查询设置的whereEqualTo("userID", userID)、orderBy("uploadTimeStamp", Query.Direction.DESCENDING)条件,你又重复追加了相同的过滤、排序语句,导致orderBy字段重复,触发了参数非法的报错。 - 你日志里看到的二次查询返回前5条是错觉:因为查询触发异常进入catch块,你打印的还是第一次查询成功后保存在
data变量里的旧数据,并非第二次查询的返回结果。
修复方案
构造下一页查询时不需要重复添加已有的过滤、排序条件,直接在原有query基础上追加startAfter和limit即可,修复后的代码如下:
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")}") // 去掉重复的whereEqualTo、orderBy条件,直接追加分页参数即可 data = data.query .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")}" ) } } }
额外优化建议
如果存在多个帖子uploadTimeStamp相同的情况,建议再补充一个排序字段(比如文档ID),避免分页边界出现漏数据或者重复数据的问题。
内容的提问来源于stack exchange,提问作者Yarin Shitrit
相关产品推荐
相关产品推荐

