fix(database): fix DatabasePagingSource pagination when using orderByChild#2336
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a new DatabasePagingKey class to replace String as the paging key in DatabasePagingSource and DatabasePagingOptions, allowing the paging source to correctly handle queries ordered by child values without producing duplicate items across pages. It also adds integration tests to verify this behavior. The review feedback suggests making DatabasePagingKey public and implementing equals() and hashCode() to ensure compatibility with the Paging library, as well as simplifying numeric type handling in startAtChildValue by checking for Number instead of Double and Long separately.
mikehardy
left a comment
There was a problem hiding this comment.
looks like a perfect fix for the existing issue but may have a not-too-hard extension possibility to be even more general and fix the general case that 2000 was just a specific instance of
…stUtils in paging test
Fixes #2000.
DatabasePagingSourcewas callingstartAt(null, key)for all queries, but Firebase Database ignores the key parameter when the query usesorderByChild(), causing every subsequent page load to return the same first page of results and throwingIllegalStateException: The same value was passed as the nextKey in two sequential Pages.The fix detects
orderByChild()queries via the internalPathIndexand callsstartAt(childValue, key)instead, storing both the child value and node key as the page cursor in the newDatabasePagingKeytype.Changes:
DatabasePagingKey— madepublic(required for cross-package Kotlin access) withequals()/hashCode()(required by the Paging library for key diffing and state restoration)DatabasePagingSource— extends cursor fix toorderByValue()queries viaValueIndexin addition toorderByChild()viaPathIndex; surfaces load errors to logcat viaonErrorReturnFirebaseRecyclerPagingAdapter— replaces deprecated@OnLifecycleEventwithLifecycleEventObserver(removed in lifecycle 2.7.0)orderByChild()