Jack Dalton
Jack Dalton

Reputation: 3681

Filtering by grandchild property in firebase [in android]

CONTEXT :

Hi, I'm currently working on an Android project backed by Firebase.

I have set up a denormalized data structure that relates polls to users (many-to-many relationship) via way of votes. Here is an image displaying the votes path of my database. The structure is as follows :

votes -> [pollUid] -> [votePushuid] -> vote object

enter image description here

So in this example we have a single poll that has 4 votes.

I want to run a check to see if a user has already voted on a poll. In order to do this I fetch the pollsUid, then run through its votes to see if any of them contain the voterUid property == to their user uid.

This is done as follows :

FirebaseHandler.getInstance().getMainDatabaseRef()
                        .child(FirebaseConstants.VOTES) //votes root
                        .child(pollKey) //polluid
                        .orderByChild("voterUid")
                        .equalTo(FirebaseHandler.getInstance().getUserUid())
                        .limitToFirst(1)
                        .addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                               if(!dataSnapshot.exists()) {

If the datasnaptshot exists then we know that the user has already voted on this poll and can handle it in the Java logic.

PROBLEM :

The datasnapshot received by onDataChange is always null (ie does not exist) when searching for a specific user's vote on a specific poll. I know for a fact that the vote exists in the db through inspecting the data, and that the userUid is correct via debugging. Removing the equalTo and limitToFirst returns all of the votes for the poll without a problem so clearly the stem of the ref is correct. This implies to me that the issue is created by one of the two methods just mentioned. Even stranger is the fact that this approach does work at certain times, but not at others.

QUESTION : How do I return a list of firebase stored objects filtered by a grandchild property? If this is not possible what would be the more appropriate datastructure for this problem?

On a further note I've seen people taking the approach of using Query instead of Databasereferences. Perhaps this might have something to do with the current issue.

Upvotes: 1

Views: 1038

Answers (1)

Wilik
Wilik

Reputation: 7720

Your query is correct. I have no problem running that query using my own DB. It's probably the userId doesn't match. DatabaseReference extends Query, that's why you can access Query's methods.

A database structure alternative would be

{ "users_votes": {
        "<userId>": {
            "<pollId1>" : true,
            "<pollId2>" : true,
            "<pollId3>" : true
        }
    }
}

Set the value to that node once the user voted to a poll.

To check if the user has voted for a poll

usersVotesRef.child(FirebaseHandler.getInstance().getUserUid())
    .child(pollKey).addListenerForSingleValueEvent(valueEventListener);

Upvotes: 1

Related Questions