hyper
hyper

Reputation: 17

How to order data on the fly

I'm a beginner with react native or firebase so I don't really know how to explain this but I have no idea on how to order received data from the database.

Let's say I have a database:

appname
   items
     -some_random_generated_string
       -name: "someString"
       -value: "999"
       -type: 0
     -some_random_generated_string
       -name: "someString"
       -value: "999"
       -type: 0

I've tried already with all order types and also setting .indexOn rule but haven't come to a solution. Also tried adding an id and then order with it and didn't come to a solution.

I guess this is accessing the database to get items so I also tried ordering them on the same line but nothing worked except limiting the amount of data.

let itemsRef = db.ref('items');

then I have:

componentDidMount() {
    itemsRef.on('value', snapshot => {
      let data = snapshot.val();
      let items = Object.values(data);
      this.setState({ items });
    });
  }

and I'm adding like this:

let addItem= (item, value, type) => {
  db.ref('/items').push({
    name: item,
    value: value,
    type: type,
  });
};

Basically what I want to achieve is to display data in reversed order than it was added so the last one added would be shown on the top.

Upvotes: 0

Views: 35

Answers (1)

Gabriel Morin
Gabriel Morin

Reputation: 2190

You could do it in two ways.

First simply call .reverse() on your current array. If you call the push method to add new items, usually the key that's assigned to each child garanties they are stored in chronological order. Therefore, calling it as such should be good enough:

componentDidMount() {
  itemsRef.on('value', snapshot => {
    let data = snapshot.val();
    let items = Object.values(data);
    items.rerverse();
    this.setState({ items });
  });
}

Though i don't know if let items = Object.values(data); garanties on every browser that your data are ordered as intended. By the way Object.values() opposed to Object.keys() is not supported on many old browsers, but if you're using it in ReactNative then it's fine.

If you want to be fully sure it's properly ordered, rewrite it as such:

componentDidMount() {
  itemsRef.on('value', snapshot => {
    let items = [];
    // forEach always send you the children in the right order
    snapshot.forEach(snap => { 
      items.push(snap.val())
    })
    items.rerverse();
    this.setState({ items });
  });
}

Finally another way to do it if you don't trust firebase's auto generated ids, is to add objects as such:

let addItem = (item, value, type) => {
  db.ref('/items').push({
    name: item,
    value: value,
    type: type,
    timestamp: new Date().getTime()
  });
};

and to use firebase's function orderByChild when you fetch the data, using timestamp as the child, and then .reverse() it again like we did previously.

Upvotes: 1

Related Questions