I have a notes app. I normally paginate the below posts-userIds node by childByAutoId
which works fine. I allow users to make edits, at which point I just update everything and add an editDate to the post itself. But that editDate is at the posts ref, not the posts-usersIds ref.
How can I paginate the posts-usersIds ref by editDate? The issue is editDates are optional, meaning they might make 200 posts, but only 2 edits or even none at all. Either way if the user wants to see the editDates first they still need to see the postDates along with them
Order would be editDates first then postDates second or if there aren't any editDates just show them all of the postDates
I was thinking instead of using a 1 as the value maybe I should put a postDate or editDate (if they made one) as the value to the posts-userIds
ref as in
-postId-123: 1 // this what I normally use, it has no meaning, just a 1 so that it has a value
-postId-123: replace the 1 with the postDate and change this to editDate when they make an edit
Maybe I could then use ref.queryOrderedByValue()
but I'm not sure.
My structure is the following:
@posts
@postId-123 // childByAutoId
-uid: "userId-ABC"
-postDate: 1640898417.456389
-editDate: 1640814049.713224 // edit date is only there if the user made an edit
@posts-userIds
@userId-ABC
-postId-123: 1
I paginate
let ref = Database.database().reference().child("posts-userIds").child(Auth.auth().currentUser!.uid)
if startKey == nil {
ref.queryOrderedByKey()
.queryLimited(toLast: 20)
.observeSingleEvent(of: .value, with: { (snapshot) in
// get posts and set startKey
})
} else {
ref.queryOrderedByKey()
.queryEnding(atValue: startKey!)
.queryLimited(toLast: 21)
.observeSingleEvent(of: .value, with: { (snapshot) in
})
}
CodePudding user response:
Firebase queries can only order/filter on a value that is (in a fixed path) under the node that it's considering to return. So you can't posts-userIds
on values from under posts
.
The solution is to duplicate the value that you want to order/filter on under posts-userIds
, either directly as the value (in which case you'll use queryOrderedByValue
for the order), or in a child property (in which case you'll use queryOrdered(byChild:)
for the order. I tend to favor the latter, simply because once there's one value you want to order/filter on, there'll often be more of them down the line.
This sort of data duplicating is quite common in NoSQL databases, so if you're not yet comfortable with it, I recommend reading NoSQL data modeling, and watching Firebase for SQL developers.