2

Basically I have played with Firebase for the past week, and I recently stumbled upon the 'queryOrderedByChild()' that as far as I know - allows you to sort data in firebase. However, I seem to not get the proper results. My Firebase data looks like this:

{
  "names" : {
    "-KHVUwXdVPHmrO_O5kil" : {
      "id" : "0",
      "name" : "Jeff"
    },
    "-KHVV7lCeac0cZNMi9fq" : {
      "id" : "3",
      "name" : "Stig"
    },
    "-KHVVCjXgl0XxasVOHF1" : {
      "id" : "13",
      "name" : "Ali"
    },
    "-KHVVJtyUO-yJZiompJO" : {
      "id" : "7",
      "name" : "Hannah"
    },
    "-KHVVR8tMSO1Oh7R8tR1" : {
      "id" : "2",
      "name" : "Amanda"
    }
  }
}

, and my code looks like this:

ref.childByAppendingPath("names")
   .queryOrderedByChild("id")
   .observeEventType(.ChildAdded) { (snapshot:FDataSnapshot!) in
       if let myID = snapshot.value["id"] as? String {
           print(myID)
       }

The output is still in a random order, displaying: 0, 2,7,1,8,4 - Isn't this supposed to be numeric? What am I doing wrong? How can I sort it so it get's numeric either ascending or descending?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
askaale
  • 1,199
  • 1
  • 23
  • 50
  • Without seeing the data, it'll be very difficult to say anything concrete. Please add a minimal snippet of the JSON that allows us to reproduce the problem. Add it as text please, which you can easily get by clicking the Export button in the Firebase dashboard. – Frank van Puffelen May 12 '16 at 04:48
  • Here is the JSON code: `{ "names" : { "-KHVUwXdVPHmrO_O5kil" : { "id" : "0", "name" : "Jeff" }, "-KHVV7lCeac0cZNMi9fq" : { "id" : "3", "name" : "Stig" }, "-KHVVCjXgl0XxasVOHF1" : { "id" : "13", "name" : "Ali" }, "-KHVVJtyUO-yJZiompJO" : { "id" : "7", "name" : "Hannah" }, "-KHVVR8tMSO1Oh7R8tR1" : { "id" : "2", "name" : "Amanda" } } } ` And the output is just in a random order showing only ID's. – askaale May 12 '16 at 08:11
  • There's an edit link under your question, so that you can add it there. That also allows you to put it in a more readable format. – Frank van Puffelen May 12 '16 at 14:49
  • @FrankvanPuffelen I edited it now. do you seem to know what the problem is? – askaale May 12 '16 at 15:51
  • Make sure that you're actually looping through the snapshot children. If you just print the snapshot it's ordered like standard JSON and not the way it came back from the firebase server. – teradyl Jul 13 '17 at 06:33

2 Answers2

2

You say that you're ordering by a number, but the value of your id property is stored as a string.

Since you're storing them as a string, they will be returned in lexicographical order.

If you want them to be in numerical order, you should store them as numbers

"-KHVUwXdVPHmrO_O5kil" : {
  "id" : 0,
  "name" : "Jeff"
},

Alternatively, you could store the ids as zero-padded strings:

{
  "names" : {
    "-KHVUwXdVPHmrO_O5kil" : {
      "id" : "0000",
      "name" : "Jeff"
    },
    "-KHVV7lCeac0cZNMi9fq" : {
      "id" : "0003",
      "name" : "Stig"
    },
    "-KHVVCjXgl0XxasVOHF1" : {
      "id" : "0013",
      "name" : "Ali"
    },
    "-KHVVJtyUO-yJZiompJO" : {
      "id" : "0007",
      "name" : "Hannah"
    },
    "-KHVVR8tMSO1Oh7R8tR1" : {
      "id" : "0002",
      "name" : "Amanda"
    }
  }
}

Since the strings are all the same length, they will be sorted in the correct order. But you'll have to decide on the length of the string/maximum id value in the latter solution, so it seems worse.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks for sorting this out for me! Do you know if this would work for a 'Double'? Let's say I want to display a new post descending (sorting the query by a timestamp of Double), would this be possible? And also, if I was to do this - could I use queryLimitedToLast instead, or both? Thanks in advance - and of course, thanks for sorting this out for me. I have to say that I am slightly embarrassed of this misconception. – askaale May 12 '16 at 19:05
  • If you're storing the doubles as a string, you'll have the same problem. But timestamps are typically milliseconds since the epoch, so regular (non-floating point) numbers, – Frank van Puffelen May 12 '16 at 20:12
  • Looks like Firebase doesn't order the Double value, even if it's stored as a double? What would you suggest to implement as data to track the date of a post being submitted by a user, for then to be read in-app how long ago it was posted? – askaale May 12 '16 at 21:11
  • Firebase orders doubles, see the [documentation on how data is ordered](https://www.firebase.com/docs/web/guide/retrieving-data.html#section-ordered-data). If you think something is wrong, create a minimal, reproduction of that problem for me to look at. It typically works best if you put that on a site like jsbin/jsfiddle. – Frank van Puffelen May 12 '16 at 21:38
  • As far as I am concerned, neither jsbin or jsfiddle supports Swift. However, I can provide you with the current Swift code that I am using - in an attempt to try to sort the Double values in a descending order. For setting a value: `ref.childByAppendingPath("posts").childByAutoId().setValue(["message":statusField.text!, "sender":"Andreas", "date":NSDate().timeIntervalSince1970]) { (error, firebase) in if error != nil { print("") } else { } } ` – askaale May 13 '16 at 18:14
  • And to retrieve the data, I use this code: `ref.childByAppendingPath("posts").queryOrderedByChild("date").observeEventType(.ChildAdded) { (snapshot:FDataSnapshot!) in var dict = [String: Any]() dict["date"] = snapshot.value["date"] as? Double dict["message"] = snapshot.value["message"] as? String self.messagesArray.append(dict) self.tableView.reloadData() } ` – askaale May 13 '16 at 18:18
0

If you using order by child you going to order your id you no going to touch it's value.

Then maybe you have to try something like

  • (FIRDatabaseQuery *) queryOrderedByValue
    queryOrderedByValue: is used to generate a reference to a view of the data that's been sorted by child value.
Achron
  • 107
  • 5