Tim Castelijn
Tim Castelijn

Reputation: 43

firebase realtime database .orderByChild not returning correct order

I am using firebase and i'd like to order my results by quoteID. However orderbychild is not getting returning the first or last item from the list that as expected.

this.props.firebase.db.ref('quotes').orderByChild("quoteId").limitToFirst(1).once("value", snapshot => {
  const entry = snapshot.val();

  console.log(entry);


})

my data structure is as follows:

{
  "1ec658d2-a7cb-45b8-8d9b-9c2a6783365d" : {
    "dateCreated" : "2019-12-02T16:06:50+01:00",
    "owner" : "DVRVSpeOXQV6wAmHAdpAe6iPQ5i2",
    "quoteID" : "200115001",
    "timeStamp" : 2075985276
  },
  "3e95a6ba-df85-4dbb-97b0-cf36df068bc1" : {
    "dateCreated" : "2019-09-27T09:17:58+02:00",
    "owner" : "xZBFCq4ho3V2G8dZTvK7RjsnTr43",
    "quoteID" : "200115002",
    "timeStamp" : 1
  },
  "d95d1f32-804b-4625-8f7e-e0bfb4f032e6" : {
    "dateCreated" : "2019-12-10T14:39:40+01:00",
    "projectName" : "testPropject timestamp2",
    "quoteID" : "191210000",
    "timeStamp" : 1575985180
  }
}

I get the entry with qouteID '200115001' returned as first single item. I cannot understand why not '191210000' is not returned first in lexographical order as described in documentation

https://firebase.google.com/docs/database/web/lists-of-data#data-order

Upvotes: 1

Views: 397

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598740

The snapshot you get from Firebase contains 3 pieces of information for each matching child node:

  1. Its key.
  2. Its value.
  3. Its relative position to the other returned child nodes.

When you call snapshot.val(), this data is converted to a simple JSON object. And in that object there is only place for two of these pieces of information: the key and the value. The order of keys in a JSON object is undefined, so the order of the results gets lost when you call snapshot.val().

To maintain the order, iterate over the child nodes with snapshot.forEach(). Something like this:

this.props.firebase.db.ref('quotes').orderByChild("quoteId").limitToFirst(1).once("value", snapshot => {
  snapshot.forEach((child) => {
    console.log(child.key);
    console.log(child.val());
  })
})

Upvotes: 1

Related Questions