Разбивка на страницы Firestore с помощью Jetpack Paging 3 — Начните, прежде чем не загрузится правильная страница

#firebase #kotlin #google-cloud-firestore #android-paging #android-paging-library

# #огневая база #kotlin #google-облако-firestore #android-подкачка #android-paging-library

Вопрос:

Это моя попытка разбить коллекцию сообщений чата Firestore на страницы с помощью Paging 3. Он правильно загружает следующие страницы, поэтому startAfter оператор, похоже, работает так, как ожидалось. Но это неправильно загружает предыдущие страницы. Вместо этого он всегда снова загружает самую первую страницу и добавляет ее в начало списка. (Я начинаю отбрасывать страницы после 100 элементов, поэтому отложенная загрузка работает в обоих направлениях).

prevKey Похоже, что оно передано правильно. Он имеет правильное значение в начале метода load непосредственно перед тем, как мы создадим запрос.

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()
    }
}
 

Ответ №1:

Вам нужно проверить тип параметров загрузки, чтобы увидеть, является ли он refresh , prepend или append .

Поскольку ваш запрос всегда извлекает элементы после в порядке убывания, когда он запрашивает добавление, вы, вероятно, загружаете неправильные элементы.