这是我尝试用Paging 3对Firestore聊天消息的集合进行分页。它正确地加载了下一页,因此startAfter
运算符似乎按预期工作。但它没有正确加载以前的页面。相反,它总是再次加载第一页,并将其附加在列表的开头。(我开始在100个项目后丢弃页面,所以懒惰加载可以双向进行(。
prevKey
似乎传递正确。在我们构建查询之前,它在加载方法的开头具有正确的值。
timeStamp
是Firestore服务器的时间戳,如果重要的话,用@ServerTimestamp
进行注释。
class ChatMessagesPagingSource(
private val messageCollection: CollectionReference
) : PagingSource<ChatMessagesPagingSource.PagingKey, ChatMessage>() {
override suspend fun load(params: LoadParams<PagingKey>): LoadResult<PagingKey, ChatMessage> {
return try {
var query = messageCollection
.orderBy("timeStamp", Query.Direction.DESCENDING)
.limit(params.loadSize.toLong())
val key = params.key
Timber.d("key = $key")
query = when (key) {
is PagingKey.PreviousKey -> query.endBefore(key.endBefore)
is PagingKey.NextKey -> query.startAfter(key.startAfter)
null -> query
}
val querySnapshot = query.get().await()
val chatMessages = querySnapshot.toObjects(ChatMessage::class.java)
val firstDoc = querySnapshot.documents.firstOrNull()
val lastDoc = querySnapshot.documents.lastOrNull()
val prevKey = if (firstDoc != null) PagingKey.PreviousKey(firstDoc) else null
val nextKey = if (lastDoc != null) PagingKey.NextKey(lastDoc) else null
Timber.d("first message: ${chatMessages.firstOrNull()}")
Timber.d("last message: ${chatMessages.lastOrNull()}")
LoadResult.Page(
data = chatMessages,
prevKey = prevKey,
nextKey = nextKey
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
sealed class PagingKey{
data class PreviousKey(val endBefore: DocumentSnapshot) : PagingKey()
data class NextKey(val startAfter: DocumentSnapshot) : PagingKey()
}
}
您需要检查LoadParams的类型,以查看它是刷新、预置还是追加。
由于查询总是按降序获取后面的项,因此当它请求预处理时,您可能加载了不正确的项。