1

I have a Firebase database structured as below

root
   - users
      -username1
         -age : 30
         -email_address : xxx@yyy.com
         -user_connections
            -username2: N
            -username3: Y
            -username4: N
      -username2
      -username3
      -username4

So far I have queried ALL users and used the result as the datasource for my FirebaseListAdapter....HOWEVER if the current user is "username1", I only want the list to show username3 (as username1 has it's "user_connections" child showing username3 as Y).

I basically want to query a dataset of all records (users) where their "user_connections" child has a value of Y. Is this possible or do I need to restructure my database?

Any help would be much appreciated.....I am very new working with Android

Below is my code

    databaseUser = FirebaseDatabase.getInstance().getReference("users");

    //initialize list view
    FirebaseListAdapter<User> fireAdapter = new FirebaseListAdapter<User>(
            getActivity(),
            User.class,
            R.layout.listview_row_search,
            databaseUser
    ) {
        @Override
        protected void populateView(View v, User model, int position) {
james murphy
  • 1,505
  • 5
  • 31
  • 57

3 Answers3

1

If I understand your question right, you are trying to query your users according to a certain condition (user_connections), Y is yes and N is no I guess. You want to show certain users and hide certain users.

Possible solution

     //in populate view

     DatabaseReference ref=FirebaseDatabase.getInstance().getReference.child("users").child(currentuser).child(model.getUser_Connections);

     ref.addValueEventListener(new ValueEventListener(){
        onDatachange{
           //here you check 
            for(DataSnapshot ds: datasnapshot.getChildren()){

                   if(ds.getKey.getValue().equals("Y")){

                       //this is the key you want to show
                       String userid_toshow=ds.getKey;



                    }

             }
        }

      });

then you check if each username under users is equal to ((userid_toshow))

to maybe show or hide layout of your list.

Hasan Bou Taam
  • 4,017
  • 2
  • 12
  • 22
  • Yes indeed that is my goal - do you know how to show/hide rows from a Firebase list adapter based on the data that come back? – james murphy Dec 09 '17 at 19:11
1

You data illustrates that you would like to represent a many to many relationship (between users). This post discusses that for a many to many relationship between 2 different entities. In your case, you have a many to many relationship between a single entity type. Although the structure you show represents all the data facts correctly and can be made to work, it won't scale as well as other representations. Below is the firebase structure that scales well and represents the same data.

root
   - users
      -username1
         -age : 30
         -email_address : xxx@yyy.com
         ... other user data
      -username2 
         ... user data goes here
      -username3
         ... user data goes here
      -username4
         ... user data goes here
 - usersRelationships
    -username1
      -username3: true
      .. no need to represent false users
    -username2
      .. user2 relationships
    -username3
      .. user3 relationships
    -username4
      .. etc
Rob Gorman
  • 3,502
  • 5
  • 28
  • 45
1

You're almost there with your Firebase database structure, but because in Firebase an important rule is to have the data as flatten as possibile, i recomand you using denormalization. For this i recomand you see this video, Denormalization is normal with the Firebase Database. So in your case, you need to move user_connections node outside user node. Because Firebase can hold boolean values, the best practice is to use true and false instead of Y and N.

Firebase-root
    |
    --- userConnections
             |
             --- username1
                    |
                    --- username3: true
                    |
                    --- username4: true

In Firebase, when we attach a listener on a specific node, the entire node is downloaded. So if you want to display for example only the name of the users, you are downloading user connections too, which is not neccessay in this case. So this is the main reason to have a database structure which looks like this.

If you want to get data from all users that belong to a particular user, you need to query your database twice and this how can be achieved this:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userNameRef = rootRef.child("users").child("userName1");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String userName = ds.getKey();

            DatabaseReference usersRef = rootRef.child("users").child(userName);
            ValueEventListener eventListener = new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    String email_address = ds.child("email_address").getValue(String.class);
                    Log.d("TAG", email_address);
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {}
            };
            usersRef.addListenerForSingleValueEvent(eventListener);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
userNameRef.addListenerForSingleValueEvent(valueEventListener);

With this code, first you are getting all user names that belong to that particular user named userName1. Second we query only those users to display their email addresses.

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