0

hi i'm trying to sort user with ascending order,firstly this my tree : enter image description here and i want to sort users by scoreTotal i have tried using categries.orderByChild("scoreTotal").orderByValue() but doesn't work here's my code :

public class Scores extends  Fragment {

    RecyclerView userlist;
    int i = 0;
    RecyclerView.LayoutManager layoutManager;
    FirebaseRecyclerAdapter<User, usersViewHolder> adapter;
    FirebaseDatabase database;
    ProgressBar loading;
    DatabaseReference categries, mDatabase;

    public Scores() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        categries = FirebaseDatabase.getInstance().getReferenceFromUrl("https://quizapp.firebaseio.com/Quizy/users");

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_scores, container, false);
        userlist = v.findViewById(R.id.users);
        loading = v.findViewById(R.id.progress);
        layoutManager = new GridLayoutManager(getActivity(), 1);
        userlist.setLayoutManager(layoutManager);
        userlist.setHasFixedSize(true);
        mDatabase = FirebaseDatabase.getInstance().getReference();
        loadCategories();
        return v;
    }

    private void loadCategories() {

        adapter = new FirebaseRecyclerAdapter<User, usersViewHolder>(User.class, R.layout.useitem, usersViewHolder.class, categries.orderByChild("scoreTotal").orderByValue()) {
            @SuppressLint("CheckResult")
            @Override
            protected void populateViewHolder(final usersViewHolder viewHolder, final User model, int position) {
                viewHolder.getUserName().setText(model.getUsername());
                viewHolder.getUserScore().setText("Score : "+model.getScoreTotal());
                RequestOptions requestOptions = new RequestOptions();
                requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL).dontTransform();
                Glide.with(getActivity()).load(model.getImageBase64()).apply(requestOptions).listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        viewHolder.getProgressBar().setVisibility(View.GONE);
                        viewHolder.getUserpic().setVisibility(View.VISIBLE);
                        return false;

                    }
                }).into(viewHolder.getUserpic());
            }


            @Override
            public usersViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                usersViewHolder viewHolder = super.onCreateViewHolder(parent, viewType);
                viewHolder.setItemOnClick(new itemOnClick() {
                    @Override
                    public void onClick(View v, int pos, boolean isLong) {

                    }
                });
                return viewHolder;
            }
        };
        adapter.notifyDataSetChanged();
        userlist.setAdapter(adapter);

    }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
ali
  • 189
  • 3
  • 14
  • check the [answer](https://stackoverflow.com/questions/34156996/firebase-data-desc-sorting-in-android) by @Frank from Firebase about sorting the data. – Niamatullah Bakhshi Mar 26 '18 at 23:59
  • This `categries.orderByChild("scoreTotal").orderByValue()` makes no sense, it should simply be `categries.orderByChild("scoreTotal")`. With that, `20` should be shown before `60`. But aside from that (as Drei answered) the order will be affected by the fact that you store the numeric values as strings. – Frank van Puffelen Mar 27 '18 at 03:31
  • add another child date and use order by child on date – Atif AbbAsi Mar 27 '18 at 05:18

1 Answers1

1

scoreTotal is a string in your database.

If you had uploaded the value as a number (generally an integer) it would not have the quotation marks around it.

The fastest solution is to reevaluate your upload code to send an int. I highly suggest this method as it is by far the fastest.

As a side note, you will need to add ".indexOn": ["scoreTotal"] to your database rules.

Additionally you could use a cloud function to parse the sting before uploading if necessary (i.e. there is for some reason no way to upload the int directly).

You could also parse and sort them pragmatically on the client side but because that's the harshest solution, I wont go into explaining it.

Drei
  • 669
  • 1
  • 6
  • 22