Reputation: 6785
I'm trying to get all my posts which time is newer ones first, I have made this query that should bring to me all the newest posts that I uploaded or other people did.
Thing is that I'm getting posts shuffled with timestamps , there are all mixed up instead of ordered by new ones
If I do the same query from the firebase console they are ordered the way it should
My recyclerview
does NOT have any reverselayout
or stackfromend
attributes and I'm not expecting to use them, instead I just want my list to come from firebase ordered
@ExperimentalCoroutinesApi
suspend fun getLatestPosts(): Flow<Result<List<Post>>> = callbackFlow {
val postList = mutableListOf<Post>()
// Reference to use in Firestore
var eventsCollection: CollectionReference? = null
try {
eventsCollection = firestore.collection("posts")
eventsCollection.orderBy("created_at", Query.Direction.DESCENDING)
} catch (e: Throwable) {
// If Firebase cannot be initialized, close the stream of data
// flow consumers will stop collecting and the coroutine will resume
close(e)
}
val suscription = eventsCollection?.addSnapshotListener { value, error ->
if (value == null) {
return@addSnapshotListener
}
try {
postList.clear()
for (post in value.documents) {
post.toObject(Post::class.java)?.let { fbPost ->
fbPost.apply {
created_at = post.getTimestamp(
"created_at",
DocumentSnapshot.ServerTimestampBehavior.ESTIMATE
)?.toDate()
}
postList.add(fbPost)
}
}
offer(Result.Success(postList))
} catch (e: Exception) {
close(e)
}
}
awaitClose { suscription?.remove() }
}
Now if I sort the list locally after getting the data that works, but I don't want it to be client side, I want to have an ordered list from the server.
What I'm doing wrong ?
Posts timestamp are saved with @ServerTimestamp
and Date format into Firestore
Upvotes: 0
Views: 37
Reputation: 317392
CollectionReference (Query) objects are immutable - they can't be changed once created. They use a builder type pattern to construct new Query objects by adding constraints. The original Query remains unmodified.
If you want to compose a set of operations to perform on a Query, you would have to remember the new Query returned by each operation. An easy way to do this is by reassigning the prior Query if you no longer need it:
var eventsQuery: Query = firestore.collection("posts")
eventsQuery = eventsQuery.orderBy("created_at", Query.Direction.DESCENDING)
Or you can do it as a chained sequence of operations, which is more idiomatic in the case that you know all the operations ahead of time:
val eventsQuery = firestore
.collection("posts")
.orderBy("created_at", Query.Direction.DESCENDING)
If you need to conditionally apply operations, however, you will need to take the first approach. A more detailed explanation can be found here: Firestore: Multiple conditional where clauses
Upvotes: 1
Reputation: 6785
Problem was at this line
eventsCollection = firestore.collection("posts")
eventsCollection.orderBy("created_at", Query.Direction.DESCENDING)
Seems like I need to wrap it up all into 1 line and make it a Query
, it does not apply any changes to the eventsCollection
, this can be done changing CollectionReference
to Query
Upvotes: 1