0

I promise an EASY read :)

Howdy, I am currently stuck. I will like to query all post starting with the newest post first instead of the oldest post. Why? Because its the only way I can include pagination in my tableView. (which means reloading when user gets to the bottom)

Lets say I have 10 posts starting with the oldest #1 and the newest #10: 1,2,...,10 If I query limited to the first 5 post I get [1,2,3,4,5] then I reverse the array, which will show [5,4,3,2,1] on my tableview starting with 5.

ISSUE: The problem is once the user gets to the bottom of the tableview, if i query the next five posts starting with the timestamp of the last post, I get... [6,7,8,9,10]

But now my table view isn't correct anymore as it will show [5,4,3,2,1,10,9,8,7,6] I am hoping that if I can use the current device date as a timestamp and query the all post before as shown below: I can essentially get [10,9,8,7,6] then when user reaches the bottom: [10,9,8,7,6,5,4,3,2,1]

let todayTime: TimeInterval = NSDate().timeIntervalSince1970

          FIRDatabase.database().reference().child("post").child(animal).queryOrderedByValue().queryEnding(atValue: todayTime, childKey: "datePost").queryLimited(toLast: 5).observe(.value, with: {(snapshot) in
AL.
  • 36,815
  • 10
  • 142
  • 281
24hrcoder
  • 15
  • 1
  • 7
  • Just write your timestamps as negative values and everything else falls into place. I wrote up an answer to another question that may help [Negative Firebase Timestamp](https://stackoverflow.com/questions/43203910/how-to-create-negative-firebase-timestamp-in-swift/43379902#43379902) – Jay Jun 19 '17 at 18:40
  • First off thanks for the response!! But hehe your answer is super complicated - I am not able to make the timestamps negative as they are made on firebase? Are you implying from you answer on your previous post, that I query the timestamp made on firebase, then make it negative? sorry not a native english speaker – 24hrcoder Jun 19 '17 at 20:09
  • As stated in the other answer, you can't directly get a timestamp from Firebase (in code) but when it's written (per the provided code in my answer), you can observe the node it's written to which will provide you the timestamp in a snapshot. You can then make it negative (in code) and write it to your nodes that need ordering. With a negative timestamp, the ordering will be via that timestamp node and naturally be in the correct sequence with the newest being 'at the top'. So the order will be -10 (newest), -9, -8....-1. So you read in -10 to -5, then -4 to -1 etc. – Jay Jun 19 '17 at 21:27
  • Hey Jay, sorry to bother but I am having issues with this part as you said in your comment [ So the order will be -10 (newest), -9, -8....-1. So you read in -10 to -5, then -4 to -1 etc. ] https://stackoverflow.com/questions/44682240/negative-timestamp-gets-the-wrong-list-of-post – 24hrcoder Jun 21 '17 at 18:46

1 Answers1

1

Given the following structure

messages
  msg_0
    msg: "oldest message"
    timestamp: -1
  msg_1
    msg: "hello"
    timestamp: -4
  msg_2
    msg: "hello"
    timestamp: -2
  msg_3
    msg: "newest message"
    timestamp: -5
  msg_4
    msg: "hello"
    timestamp: -3

and the following code

let messagesRef = self.ref.child("messages")
let queryRef = messagesRef.queryOrdered(byChild: "timestamp")
queryRef.observe(.childAdded, with: { snapshot in
    let key = snapshot.key
    print(key)
})

the output will be

msg_3 <-newest message
msg_1
msg_4
msg_2
msg_0 <-oldest message

As you can see, msg_3 is the newest message and appears 'at the top' i.e. it's the first snapshot the query receives. If you are populating an array to be used as a datasource, this will be added at index 0, then msg_1 would be at index 1 etc.

If the user scrolls and you want to load the next 5, it would be timestamps 6 to 10, with 10 being the newest.

Now suppose you want to load in the oldest two messages. Here's the query

let queryRef = messagesRef.queryOrdered(byChild: "timestamp")
                          .queryStarting(atValue: -3, childKey: "timestamp")
                          .queryEnding(atValue: -1, childKey: "timestamp")

the result

msg_2
msg_0

then, we want to load in the next oldest two

let queryRef = messagesRef.queryOrdered(byChild: "timestamp")
                          .queryStarting(atValue: -5, childKey: "timestamp")
                          .queryEnding(atValue: -3, childKey: "timestamp")

which gives us

msg_1
msg_4

Obviously I substitutes -5, -4 etc for an actual timestamp but it would work the same way.

Jay
  • 34,438
  • 18
  • 52
  • 81
  • Hey Jay the thing is I don't know what the **ending value** is hehehehe... I tried using the current time and even just plainly 1 with no success? Last last last tip – 24hrcoder Jun 21 '17 at 22:15
  • @24hrcoder If the answer helped please accept the answer so it can help others! – Jay Jun 22 '17 at 01:52
  • Yeah sorry, I tried liking multiple times, but it says "votes cast by those with less than 15 reps. are recorded but do not change the publicly displayed post score" – 24hrcoder Jun 22 '17 at 02:01