Q:

How to get messages ordered by timestamp

i want to get all messages by their creation date (which is timestamp).
My data structure looks like this:
messages
  XRJONcahNUgeNrfkH3cmITJt3409 (auto uid of owner - user)
    -KoOSxA2Iajk3kv20U_p (automatic uid generated by Firebase)
      message: "Hi"
      senderId: "X8Oxg5J9Imb12C1iYBXJT9P48909"
      senderName: "Dave"
      timestamp: 1505813320526 (automatic timestamp)
    -GdOSxR2Iajk3kv20U_p --- I NEED TO SORT THESE UIDS
      message: "Hello"
      senderId: "G7Oxg5J9Imb12C1iYBXJT9P48909"
      senderName: "Frank"
      timestamp: 1505813321024 (automatic timestamp)

And I get all messages like this:
database.child("messages").child(ownersId).observeSingleEvent(of: .value, with: { (snapshot) in
            print(snapshot)
            if let messagesDict = snapshot.value as? [String:AnyObject] {
                for (_,message) in messagesDict {
                    self.messages.append((message["message"] as? String)!)
                    self.users.append((message["senderName"] as? String)!)
                    self.timestamps.append((message["timestamp"] as? IntMax)!)
                }
            }
            completionHandler(true)

        }) { (error) in
            print(error.localizedDescription)
            completionHandler(false)
        }

So the question is, how can I get all messages ordered from the oldest to the newest? I dont know how can I use ordering methods (queryOrderedByKey(), queryOrderedByValue() or queryOrdered(byChild: "timestamp") in this specific case. Firebase sends me data in random order (I dont know if it is random, but it is not sorted by date).

A:

As Rashwan said, you'll need to call queryOrderedByChild() to get the items returns in the correct order. Then you loop over snapshot.children to ensure you also process them in the correct order.
So:
database.child("messages").queryOrdered(byChild: "timestamp").observe(.value, with: { snapshot in
    for child in snapshot.children.allObjects as! [DataSnapshot] {
        print("\(child.key)")
    }

    completionHandler(true)
})

The important thing inside the callback is to not convert the entire snapshot into a dictionary, because the dictionary won't maintain the order of the items.

