0

I am using FirebaseRecyclerAdapter.

I have many nodes with a child "maxValue". Let's say I have five nodes, the max values of each when listed are 34, 210, 90, 315, 74.

I expected .oderByChild("maxValue") to order them like this: 315, 210, 90, 74, 34.

However, it returns them as 90, 74, 210, 34, 314.

So it is checking the first digit, then if two entries have the same first digit, it then sorts by the second digit.

I need to it to sort by the value of the whole number. Is this possible or will I have to take the data and sort it myself?

Edit: Here is my full code setting up the FirebaseRecyclerAdapter.

Query query = databaseReference.orderByChild("maxValue");

FirebaseRecyclerOptions<ExerciseMaxesModelClass> options = new FirebaseRecyclerOptions
                .Builder<ExerciseMaxesModelClass>()
                .setQuery(query, ExerciseMaxesModelClass.class)
                .build();

        firebaseAdapter = new FirebaseRecyclerAdapter<ExerciseMaxesModelClass, ExerciseMaxesViewHolder>(options) {
            @Override
            protected void onBindViewHolder(@NonNull ExerciseMaxesViewHolder holder, int position,
                                            @NonNull ExerciseMaxesModelClass model) {

                holder.setDate(model.getDate());
                holder.setExerciseName(model.getExerciseName());
                holder.setIsImperial(model.isIsImperial());
                holder.setIsImperialPOV(isImperial);
                holder.setMaxValue(model.getMaxValue());

            }

            @Override
            public ExerciseMaxesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

                View view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.exercise_maxes_list_item, parent, false);

                return new ExerciseMaxesViewHolder(view);
            }
        };

What an example node looks like:

Bench Press (Barbell - Flat)
    - date: "2019-11-28"
    - exerciseName: "Bench Press (Barbell - Flat)"
    - isImperial: true
    - maxValue: "315"

Edit 2: I'm happy with the workaround I've posted as an answer, but apparently I can't accept my own answer yet. Now that I'm looking at the node, the answer might simply be because I am storing the max value as a string, so it of course doesn't sort it as an int.

therealone
  • 421
  • 10
  • 22
  • Please add your database structure as a JSON file or at least a screenshot. – Alex Mamo Mar 26 '20 at 13:35
  • Ok, I've edited in an example node if you're curious, but I'm good with the workaround I made, which I'll accept as answer when it lets me tomorrow if no one knows a way to make it work with FirebaseRecyclerAdapter. – therealone Mar 27 '20 at 08:42

2 Answers2

0

Firebase sorts the data by ascending order, that's why you get 90, 74, 210, 34, 314. The only way is to retrieve them and then add the data to a List, and do:

Collection.reverse(myList);

https://firebase.google.com/docs/database/android/lists-of-data

https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#reverse-java.util.List-

Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
  • I forgot to add, I'm using the FirebaseRecyclerAdapter. So I'm not getting a list from Firebase and then putting that list into my own adapter, which would allow me to sort the data before displaying it. Could you take a look at my edited main post, I'll post the full code I'm using. Let me know though if this method isn't possible with FirebaseRecyclerAdapter, because I'm not just getting the values and sorting them, I'm getting the full model class of each node. – therealone Mar 26 '20 at 09:26
  • If it's not possible with FirebaseReyclerAdapter, I could sort the list of models manually, input them in order into a hashmap and pass that to a custom adapter. Doing it with the Firebase Adapter would be ideal though of course. – therealone Mar 26 '20 at 09:31
  • can you check this https://stackoverflow.com/questions/33830387/how-reverse-the-data-fetched-with-firebaseui-android – Peter Haddad Mar 26 '20 at 09:45
  • Ok, tried it, all it does is reverse the sorting of the list. So it becomes 210, 314, 34, 74, 90. – therealone Mar 26 '20 at 10:00
0

Edit: It is probably because I am storing the value as a string and not an int. Sometimes it's the simplest thing.

Here's my workaround code anyway, in case you need the number stored as a string for whatever reason.

Go through each node at the specific database reference, adding each ModelClass to an arraylist. Then use Collections.sort on that arraylist. It's actually pretty easy to sort a list of objects by a variable. Then make a quick adapter using the ViewHolder class you were already using in your FirebaseReyclerAdapter, and add the now sorted list.

My workaround code looks like this:

// within .addListenerForSingleValueEvent's onDataChange method
int inc = 0;
for(DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()){

    modelClassArrayList.add(dataSnapshot1.getValue(ExerciseMaxesModelClass.class));

    inc++;

    if(inc == dataSnapshot.getChildrenCount()){

        Collections.sort(modelClassArrayList, new Comparator<ExerciseMaxesModelClass>() {
            @Override
            public int compare(ExerciseMaxesModelClass o1, ExerciseMaxesModelClass o2) {
                return Double.compare(Double.parseDouble(o1.getMaxValue()),
                                        Double.parseDouble(o2.getMaxValue()));
                }
            });

        MaxesAdapter adapter = new MaxesAdapter(modelClassArrayList, isImperial);

        recyclerView.setAdapter(adapter);

    }
}
therealone
  • 421
  • 10
  • 22