Query not returning correct items in list. Should return items with largest count and list limit should be 15 items

I need to make it so that the ArrayList can only have 15 items. I have tried the two obvious things that one could do which is:

if (mPostList.size() < 15)

and

if (mRecyclerView.getAdapter().getItemCount() < 15)

I have tried both of those approaches, but they don't return the correct items. The items that are to be queried are by count from the most to the least, and both of those return random items that shouldn't be in the list.

Below you have the whole method for context. What can I do so that I get back the posts with the biggest count and only have 15 items in the list?

If I change it to DatabaseReference instead of Query it works but takes WAY TOO LONG.

Need it to be ordered by count and set the list limit to 15 items.

So how can I limit the list to 15 items for Query?

Posts
    -MFv4Q2HuSMeO20jFdvn
        city: "New Orleans"
        count: 13
        description: "Who's down for a little nature hike with some g..."
        postid: "-MFv4Q2HuSMeO20jFdvn"
        postimage: "https://firebasestorage.googleapis.com/v0/b/eve..."
        publisher: "p3IeqP273ogiWuexi6w0bNGm9Mo2"
        location: "2615 Stonebriar Ridge Ct"
        timestamp: 1598719111494

        private void readPosts() {
            Query query = FirebaseDatabase.getInstance().getReference("Posts").orderByChild("count");
            query.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    mPostList.clear();
                    for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                        Post post = dataSnapshot.getValue(Post.class);
                            mPostList.add(post);
                    }
    
                    if (mPostList.size() == 0) {
                        mProgressBar.setVisibility(View.GONE);
                        mNoEventsFoundTextView.setVisibility(View.VISIBLE);
                    } else {
                        mProgressBar.setVisibility(View.GONE);
                        mNoEventsFoundTextView.setVisibility(View.GONE);
                    }
    
                    Collections.sort(mPostList, (Post o1, Post o2) -> Long.compare(o2.getCount(), o1.getCount()));
                    mPostAdapter.notifyDataSetChanged();
                    mSwipeRefreshLayout.setRefreshing(false);
                }
    
                @Override
                public void onCancelled(@NonNull DatabaseError error) {
                    mSwipeRefreshLayout.setRefreshing(false);
                }
            });
        }

1 answer

  • answered 2020-09-24 18:14 Frank van Puffelen

    Firebase Realtime Database queries always return the matching nodes in ascending order. So if you want the 15 items with the highest values, you have two options:

    1. Get the last 15 items from the list, and then reverse those client-side. The query for this would look like this:

      query = FirebaseDatabase.getInstance().getReference("Posts")
                              .orderByChild("count").limitToLast(15)            
      
    2. Store an inverted count value in each child node too, and order on that. So each JSON would then look like this:

      Posts
          -MFv4Q2HuSMeO20jFdvn
              city: "New Orleans"
              count: 13
              invertedCount: -13
              ...
      

      And the query would be:

      query = FirebaseDatabase.getInstance().getReference("Posts")
                              .orderByChild("invertedCount").limitToFirst(15)
      

    Also see: