Mr Robot
Mr Robot

Reputation: 897

Sorting the Firebase snapshot before setting values to state

I am getting values from Firebase, since Firebase do not support combining multiple orderByChild(), I guess we have to sort the values at client side

The Firebase query is

componentDidMount() {
    const device_id = DeviceInfo.getUniqueID();
    this.codesRef = firebase.database().ref(`codes`).orderByChild('owner').equalTo(device_id);
    this.codesRef.keepSynced(true);
    this.codesRef.on('value', this.handleCodesUpdate);
}

componentWillUnmount() {
    this.codesRef.off('value', this.handleCodesUpdate);
}

handleCodesUpdate(snapshot) {
    if (snapshot.val()) {

        //sort the snapshot before assigning to state

        this.setState({ codes: snapshot.val() });
    }
    else {
        this.setState({ codes: {} });
    }
}

the firebase response

{ 
   "-L1SI6Ceu2mPCxDU89NH":{  
      "status":0,
      "purchase_date":1514467520472,
      "title":"Mnic Htod",
      "start_in":0,
      "owner":"fgdgfdgdfgdfgdfgdfg",
      "valid_duration":1,
      "createdAt":"2017-11-28 18:55:20",
      "code":"218688"
   },
   "-L1SI3krvOYDaqr8g_cs":{  
      "status":0,
      "purchase_date":1514467510437,
      "title":"Banfog",
      "start_in":0,
      "owner":"xgdfgdfgdfgfdgdf",
      "valid_duration":1,
      "createdAt":"2017-11-28 18:55:10",
      "code":"804452"
   },
   "-L1SI1eFHX7a0_RFhZtW":{  
      "status":0,
      "purchase_date":1514467501822,
      "title":"Blizaard",
      "start_in":0,
      "owner":"xcvxcvxcvxcvxcv",
      "valid_duration":1,
      "createdAt":"2017-11-28 18:55:1",
      "code":"300149"
   }
}

I want to sort the data by createdAt

Looking forward for much needed help

Thank you

Upvotes: 0

Views: 2356

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598817

The simplest way is with a snippet like this:

var sortedKeys = Object.keys(json).sort(function(a,b) { 
  return json[b].createdAt < json[a].createdAt 
});

See this runnable version:

var json = { 
   "-L1SI6Ceu2mPCxDU89NH":{  
      "status":0,
      "purchase_date":1514467520472,
      "title":"Mnic Htod",
      "start_in":0,
      "owner":"fgdgfdgdfgdfgdfgdfg",
      "valid_duration":1,
      "createdAt":"2017-11-28 18:55:20",
      "code":"218688"
   },
   "-L1SI3krvOYDaqr8g_cs":{  
      "status":0,
      "purchase_date":1514467510437,
      "title":"Banfog",
      "start_in":0,
      "owner":"xgdfgdfgdfgfdgdf",
      "valid_duration":1,
      "createdAt":"2017-11-28 18:55:10",
      "code":"804452"
   },
   "-L1SI1eFHX7a0_RFhZtW":{  
      "status":0,
      "purchase_date":1514467501822,
      "title":"Blizaard",
      "start_in":0,
      "owner":"xcvxcvxcvxcvxcv",
      "valid_duration":1,
      "createdAt":"2017-11-28 18:55:1",
      "code":"300149"
   }
}
var sortedKeys = Object.keys(json).sort(function(a,b) { return json[b].createdAt < json[a].createdAt });
console.log(sortedKeys);

A few things to note:

  1. You cannot get Firebase to do this operation server-side, since it can only order/filter on a single property. See http://stackoverflow.com/questions/26700924/query-based-on-multiple-where-clauses-in-firebase.
  2. You're throwing the order information that Firebase returns for the data away when you call snapshot.val(). I don't think that's a problem here, but if you want to maintain that ordering, use snapshot.forEach() to loop over the results. See orderByChild not working in Firebase.
  3. Your date format seems flawed in the last child: "createdAt":"2017-11-28 18:55:1". That should be "createdAt":"2017-11-28 18:55:01" to make it reliably sortable.

Upvotes: 2

Related Questions