3

I am developing a forum kind of app where users can post questions and tag them with related technologies.

The app has the modules and database similar to the Firebase database repo.

I wanted to filter the posts according to their tags. As filtering on server-side is not possible for multiple key values, I had to approach a way to filter it before populating in RecyclerView.

I referred a lot of questions here and found Puf's answer relevant for this case.

This is my JSON tree

"posts" : {
"-Kdb0BsybfpPtkAPRF1-" : {
  "author" : "Anush Surendran",
  "body" : "Test 1 ",
  "commentCount" : 0,
  "created" : 1487787053303,
  "starCount" : 1,
  "stars" : {
    "v9KTwyI2DMbDgKHALgPSJEBK3fi1" : true
  },
  "tag" : "#CSS",
  "title" : "Checking Post Time",
  "uid" : "BvNgX2U5U4SriTWsoEtqbGYgOTw1"
},
"-Kdb2D9vD-3kHWpCMIFi" : {
  "author" : "Anush Surendran",
  "body" : "Abc",
  "commentCount" : 0,
  "created" : 1485000000000,
  "starCount" : 0,
  "tag" : "#HTML",
  "title" : "Test 2",
  "uid" : "BvNgX2U5U4SriTWsoEtqbGYgOTw1"
}

I am overriding parseSnapshot with the following logic

    @Override
    protected Post parseSnapshot(DataSnapshot snapshot) {
        if (snapshot.getValue(Post.class).tag.equals("#HTML")){
            Log.d(TAG,"gotHTML Filtered Posts");
            return snapshot.getValue(Post.class);
        }
        else
        return super.parseSnapshot(snapshot);
    }

Trying with just one value now. I'll put this in a loop to filter multiple tags (say HTML, CSS, JS)

The code works fine and I could see the if condition work as expected.

I couldn't figure out what to return in the else part if there are no posts with specific tag. The current else part returns all posts.

Is there a better way to filter data as compared to this?

Any help would be greatly appreciated!

Community
  • 1
  • 1

2 Answers2

3

You can get the filtered data from firebase instead of taking all the data and filtering it in client.

DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
Query postsQuery = mDatabase.child("posts").orderByChild("tag").equalTo("#HTML");
mAdapter = new FirebaseRecyclerAdapter<Post, PostViewHolder>(Post.class, R.layout.item_post, PostViewHolder.class, postsQuery) {
            @Override
            protected void populateViewHolder(final PostViewHolder viewHolder, final Post model, final int position) {
                final DatabaseReference yourRef = getRef(position);
                viewHolder.bindToPost(model,getContext());

            }
        };
        mRecycler.setAdapter(mAdapter);
AtaerCaner
  • 691
  • 7
  • 12
  • 1
    Thanks for the help! I know to retrieve it this way. But this only works for one value, not for multiple equal to values as I mentioned. So the only way is to parse it before populating. – Anush Surendran Feb 26 '17 at 17:06
2

Overriding parseSnapshot can be used to map the view to a subset of the data in the snapshot. If cannot be used to filter data.

There currently is no way to filter data on the client with FirebaseUI. There is an open feature request for it: https://github.com/firebase/FirebaseUI-Android/issues/15. As you can see in that issue, it's a contentious feature.

As Morgan says there:

[FirebaseUI] has filtering as a deliberate non-goal, since we don't want to encourage greedily pulling data that may never be displayed.

I'd definitely fear for retrieving too much data in your scenario. It'd be much better to come up with a data model that allows the required filtering to be done on the server.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 1
    Really appreciate your help! I did follow on the feature request as well. Is there a work around for this? Because I only want to filter based on one key (tag in database). I couldn't think of a model which helps in this case. – Anush Surendran Feb 26 '17 at 18:01
  • In the JSON snippet you've shared, you could simply query `FirebaseDatabase.getInstance().ref("posts").orderByChild("Tag").equalTo("#HTML")`. But if each item can have multiple tags, see http://stackoverflow.com/questions/40656589/firebase-query-if-child-of-child-contains-a-value – Frank van Puffelen Feb 26 '17 at 18:40