0

I am working on an application similar to tinder but to help users to find people to play a specific sport with. I currently have the code searching the database for the gender of the users (that the user can be matched with). However each user in the database has a node that contains all of the sports the user can pick. If the user prefers a sport the value is saved as 'true' and if not, the value is saved as 'false'. The appropriate users are then shown on the app.

A screenshot of the database is shown below:

https://i.stack.imgur.com/LdefD.png

This is the code I have so far:

 public void checkUserSex(){
    final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    DatabaseReference userDb = usersDb.child(user.getUid());
    userDb.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()){
                if (dataSnapshot.child("sex"). getValue() != null){
                    userSex = dataSnapshot.child("sex").getValue().toString();
                    switch (userSex){
                        case "Male":
                            oppositeUserSex = "Female";
                            break;
                        case "Female":
                            oppositeUserSex = "Male";
                            break;
                    }
                    getOppositeSexUsers();
                }
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}

public void getOppositeSexUsers(){
    usersDb.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            if (dataSnapshot.child("sex").getValue() != null) {
                if (dataSnapshot.exists() && !dataSnapshot.child("connections").child("pass").hasChild(currentUId) && !dataSnapshot.child("connections").child("play").hasChild(currentUId) && dataSnapshot.child("sex").getValue().toString().equals(oppositeUserSex)) {
                    String profileImageUrl = "default";
                    if (!dataSnapshot.child("profileImageUrl").getValue().equals("default")) {
                        profileImageUrl = dataSnapshot.child("profileImageUrl").getValue().toString();
                    }
                    cards item = new cards(dataSnapshot.getKey(), dataSnapshot.child("name").getValue().toString(), profileImageUrl);
                    rowItems.add(item);
                    arrayAdapter.notifyDataSetChanged();
                }
            }
        }
        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
        }
        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}

How do I change it from matching gender to matching the selected sport?

KENdi
  • 7,576
  • 2
  • 16
  • 31
  • The problem with your current data structure is that you'd need to define an index on each individual `Sport` value, which is often not feasible. That's why it's better to create your own inverted lookup structure, as Alex' answer shows. For another explanation, have a look at my answer here: https://stackoverflow.com/questions/40656589/firebase-query-if-child-of-child-contains-a-value – Frank van Puffelen Mar 14 '18 at 14:25

1 Answers1

1

Unfortunately, Firebase Realtime database does not allow a query based on multiple properties. To achieve what you want, you don't need to restructure your database entirely, you just need to change it a little bit. To solve this problem, you need to add a new node for each sport. Every time you add a new user which plays golf, add it also in its corresponding sport node. Your new node should look like this:

Firebase-root
    |
    --- golfPlayers
           |
           --- userId1 : true
           |
           --- userId2 : true

With this structure you can query your database to get only the users who are playing golf. This can be done by attaching a listener on golf node and iterate on the DataSnapshot object.

This practice is called denormalization and is a common practice when it comes to Firebase. For a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Database.

Note, what you are trying to do and cannot be solved using Firebase Realtime database, can be solved using Cloud Firestore. Give it a try.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193