3

I want to order my posts in the FirebaseRecyclerView by the String Votes. It contains a number as a String. If I write orderbychild("Votes") it shows up the smallest number first.

How can I turn that around? Cheers!

AL.
  • 36,815
  • 10
  • 142
  • 281
Markus Biermeier
  • 103
  • 1
  • 11
  • try http://stackoverflow.com/questions/38303830/how-to-retrieve-data-from-firebase-database-in-descending-order – Sahaj Rana Jan 05 '17 at 16:19
  • Invert the vote count. When a post is "upvoted", subtract one from the count. Then the post with the most votes has the smallest vote count and appears first in the query result. – Bob Snyder Jan 05 '17 at 16:43

5 Answers5

3

A quick and rather flexible way to do this on server side is to add an extra field and index your data both with Votes and negativeVotes, where negativeVotes=-Votes

Then for reverse order you do this:

orderbychild("negativeVotes")

And for regular order you do this:

orderbychild("Votes")
Ari
  • 7,251
  • 11
  • 40
  • 70
2

You don't necessarily turn it around.

Let's say your data looks like this:

{ 
    "polls":  {
        "id1": { "name": "lorem", "votes": 4 }
        "id2": { "name": "ipsum", "votes": 3 }
        "id3": { "name": "dolor", "votes": 5 }
        "id4": { "name": "sit", "votes": 2 }
        "id5": { "name": "amot", "votes": 6 }
    }
}

If for instance you need the top 4 you would do this:

.orderByChild("Votes").limitToFirst(4)

Would return:

{
    "id4": { "name": "sit", "votes": 2 }            
    "id2": { "name": "ipsum", "votes": 3 }
    "id1": { "name": "lorem", "votes": 4 }          
    "id3": { "name": "dolor", "votes": 5 }
}

If you want the other end, you would do this instead:

.orderByChild("Votes").limitToLast(4)

And the return would be:

{
    "id2": { "name": "ipsum", "votes": 3 }
    "id1": { "name": "lorem", "votes": 4 }          
    "id3": { "name": "dolor", "votes": 5 }
    "id5": { "name": "amot", "votes": 6 }
}

If you need all of them, just order in the ui.

Mathew Berg
  • 28,625
  • 11
  • 69
  • 90
  • I've done it like this, but it orders it to the smallest number first 3,4,5,6 i want it that the biggest number comes first. How can i do that? – Markus Biermeier Jan 05 '17 at 16:35
  • 1
    Once you get the data, you'll have to order it in the ui. – Mathew Berg Jan 05 '17 at 16:53
  • @MarkusBiermeier in Firebase Database (for now) this is the best and easiest way to get what you are looking for. If you have toruble sorting the data after you get them, please get some more reference by googling or searching this site :) – koceeng Jan 06 '17 at 05:37
  • 1
    This ain't an answer. – Kishan Solanki Jul 06 '18 at 11:57
1

A way that I think better is ordering in client-side using reverse().

mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
Diego Venâncio
  • 5,698
  • 2
  • 49
  • 68
0

the code below is how I fixed the issue. it uses an 3 integers - a max value the max value is equal to what ever you want with in the bounds of the datatype restrictions.

int round = 5;
int roundKills = 1000;
int points = 500;
round = round-99999;
roundKills = roundKills-999999;
points = points-99999999;
String oundkills = Integer.toString(roundKills);
String oints = Integer.toString(points);
String ound = Integer.toString(round);

LeaderBoardInput leaderBoardInput = new 
LeaderBoardInput(user,"SM",oundkills,oints,ound);
            

the LeaderboardInput class is just getters and setters for values that are being passed to the database

reference.child(user+System.currentTimeMillis()).setValue(leaderBoardInput);

when you pull the value, you would do something like the following:

round = round+99999;
roundKills = roundKills+999999;
points = points+99999999;

for your example if you have 5 votes and a max vote of 9,999,999 the code would look like this

int votes = 5;
long invertVotes = votes - 9999999;
String dbVotes = Integer.toString(invertVotes);
rootNode = FirebaseDatabase.getInstance();
reference = rootNode.getReference("scores");
reference.child("Votes"+System.currentTimeMillis()).setValue(dbVotes);
Query reference = FirebaseDatabase.getInstance()
                    .getReference().child("Votes").orderByChild("Votes");

                reference.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        //parse data to recycler view adapter and call //notifyDatasetChange()
                            Iterable<DataSnapshot> children = dataSnapshot.getChildren();
                            for (DataSnapshot child : children) {
                                Votes voteValues = child.getValue(voteinput.class);
int value = votevalues.getvotes()+9999999;
                                scores.add(new Votes( value));
                              
                            }
                            getdb = false;
                    }
                });

with Votes be a getter setter class and the scores variable being a list of the Votes class instances this will order votes 9999994 in db but print 5 to list out put of multiple values will 5 4 3 2 1 instead of 1 2 3 4 5

0

I would like to add just one more thing to @Ari approch.

private Query getQuery() {
    Query query;
    if(last_value == -1) {
        query = getPostViewCountRef()
                .orderByChild("negativeViewsCount")
                .limitToFirst(ITEMS_PER_PAGE);
    }else {
        query = getPostViewCountRef()
                .orderByChild("negativeViewsCount")
                .startAfter(last_value)
                .limitToFirst(ITEMS_PER_PAGE);
    }
    return query;
}

as you can see we limitToFist instead of limitTolast