4

enter image description here

var playersRef = firebase.database().ref("team_mapping/");


playersRef.orderByChild("score").limitToFirst(7).on("child_added", function(data) {
}

Using this query, I can sort it in ascending order. But, I wanted to sort in descending order. Can any body suggest me with some way to do this. Any help will be appreciated.

Thanks in Advance!!

Mike McDonald
  • 15,609
  • 2
  • 46
  • 49
Santosh
  • 297
  • 1
  • 4
  • 15
  • You can use priorities I guess https://firebase.google.com/docs/reference/js/firebase.database.Reference#orderByPriority – Arnelle Balane Apr 06 '17 at 11:13
  • 1
    we can use only one order .. & orderByPriority() doesn't take any argument to pass . so it's coming as it is . – Santosh Apr 06 '17 at 11:23
  • Thanks fr your try .I ran the query like this . Can you see & correct it if required var playersRef1 = firebase.database().ref("team_mapping/"); playersRef1.orderByPriority().on("child_added", function(data) { console.log("Score valus------->"+data.val().score); }) – Santosh Apr 06 '17 at 11:25
  • 1
    see if this helps: http://stackoverflow.com/a/40280032/1753177 – lambodar Apr 06 '17 at 11:36
  • I believe you'll need to set the priorities for each item for the `orderByPriority` to work properly https://firebase.google.com/docs/reference/js/firebase.database.Reference#setPriority – Arnelle Balane Apr 06 '17 at 11:47
  • 2
    priorities will also always be ordered in ascending order, but you can control the value for the priorities, so you can for example set a priorities to be the negative of the `score` – Arnelle Balane Apr 06 '17 at 11:49
  • thanks . Can you help me in my code how to implement it . I tried many ways . I am confused what argument i should pass on to parameters of setPriority(). – Santosh Apr 06 '17 at 11:55
  • @ArnelleBalane till now i didn't find a way to sort in descending order .. could you help me out with this ? – Santosh Apr 17 '17 at 09:53

3 Answers3

5

just use reverse() on the array , suppose if you are storing the values to an array items[] then do a this.items.reverse()

ref.subscribe(snapshots => {
       this.items = [];
      snapshots.forEach(snapshot => {

        this.items.push(snapshot);

      });
      **this.items.reverse();**
    },
sajanthomas01
  • 367
  • 5
  • 14
1

You can limit to the last 7 which will give you the highest scores since the query is in ascending order. Then all you have to do is reverse the last 7 you get for them to be in descending order.

var playersRef = firebase.database().ref("team_mapping/");
var playersData = [];
var pageCursor;

playersRef.orderByChild("score").limitToLast(7).on("child_added", function(data) {
    playersData = [data] + playersData;
}

UPDATE

Here is an example of how you could paginate by score.

const query = firebase.database().ref("team_mappings").orderByChild('score');

var snapshots = [];

function reversedChildren(snapshot) {
    var children = [];
    snapshot.forEach(function (child) { children.unshift(child); });
    return children;
}

function addPlayerToLeaderBoard(snapshot) {
    var key = snapshot.key;
    var place = snapshots.indexOf(snapshot) + 1;
    var score = snapshot.child('score').val();
    $('#leaderboard').append(`<li><b>${key}: ${score}</li>`);
}

function parsePage(snapshot) {
    var children = reversedChildren(snapshot);
    children.forEach(function (child) {
        players.push(child);
        addPlayerToLeaderBoard(child);
    });
    pageCursor = children[children.length - 1];
}

function reloadPlayers() {
    players = [];
    pageCursor = null;
    query.limitToLast(5).once('value').then(parsePage);
}

function loadMorePlayers() {
    query.endAt(pageCursor).limitToLast(5).once('value').then(parsePage);
}

reloadPlayers();

$('#reload').on('click', reloadPlayers);
$('#load_more').on('click', loadMorePlayers);
Callam
  • 11,409
  • 2
  • 34
  • 32
  • I had tried this 1 also .. same ascending order it's coming . Any other suggestions can help me .. – Santosh Apr 12 '17 at 04:49
  • how to do this . can you please help me out ! – Santosh Apr 12 '17 at 05:31
  • Thanks . but i am not getting the output as required . Earlier i was getting sorted scores from this data.val().score; Now if i append into this array it's getting inserted into same order . Now can you please help me how to iterate & sort this array into descending order – Santosh Apr 12 '17 at 06:27
  • var playersRef1 = firebase.database().ref("team_mapping/"); playersRef1.orderByChild("score").limitToLast(7).on("child_added", function(data) { console.log("scores are ::"+data.val().score); }) – Santosh Apr 12 '17 at 10:53
  • if i put into an array it will look like this var playersRef1 = firebase.database().ref("team_mapping/"); var scores=[]; playersRef1.orderByChild("score").limitToLast(7).on("child_added", function(data) { // console.log("Score valus------->"+data.val().score); //$scope.scores=data.val().score; scores=[data] + scores; // debugger; console.log(scores); }) – Santosh Apr 12 '17 at 10:55
  • What happens when I want to do pages? I can't just use limitToLast...I have to use startAt and endAt... – Aero Wang Aug 15 '17 at 05:59
  • @Callam thanks but this method doesn't seem to give the numbers of pages. Which requires a `.once()` to just get the length of the list...let's say if my list is 4GB, it will need to download 4GB to just show how many pages there are... – Aero Wang Aug 16 '17 at 02:31
  • Why do you need the number of pages? – Callam Aug 16 '17 at 02:47
  • Also it will return `cursor` undefined since it hasn't been inited. – Aero Wang Aug 16 '17 at 02:47
  • @Callam so people can click on them to jump to other pages. – Aero Wang Aug 16 '17 at 02:48
  • It's just an infinite scroll implementation, if you want the number of pages, you would have to keep a count at `team_mappings/count` among the child nodes. – Callam Aug 16 '17 at 02:48
  • Do explain how to create a count if I haven't kept one. – Aero Wang Aug 16 '17 at 02:50
  • https://stackoverflow.com/questions/42914815/cloud-functions-for-firebase-increment-counter – Callam Aug 16 '17 at 02:51
  • How even if you did have the number of `team_mappings`, it would still be difficult to jump to a specific page. You would have to load the pages before the requested page. – Callam Aug 16 '17 at 02:53
  • Also `players[players.length - 1].child('score').val()` doesn't work when I have a list of 5 millions of the score value at 0, 48 millions of the score value at 1... – Aero Wang Aug 16 '17 at 02:54
  • @AeroWang I have updated my answer to fix that. You might need to keep an updated leaderboard in your database where the keys of each player is their leaderboard ranking. I think you should open your own question specific to your database structure. – Callam Aug 16 '17 at 02:58
0

Unfortunatelly, there is not a shortcut for this yet. However, if you are using Listview or Recyclerview as UI, you could simply solve this issue by reversing the UI,by reversing Listview or Recyclerview

For Recyclerview you could reverse as follows:

LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager)

For Listview:

listView.setStackFromBottom(true);
Burak
  • 319
  • 5
  • 16