1

Say I have an app with users who own pets.

From what I read in different sources, this is a valid way to model relations in Firebase DB:

{
  "users":{
    "user1":{
      "name":"Arthur",
      "pets":{
          "pet1":true,
          "pet2":true
      }
    },
    "user2":{
      "name":"George",
      "pets":{
        "pet3":true,
        "pet4":true
      }
    }
  },
  "pets":{
    "pet1":{...},
    "pet2":{...},
    "pet3":{...},
    "pet4":{...}
  }
}

Say I have an Android app, and I want to present a list of all of the users, and in each list item to also mention what pets that user owns.

What I want is a list of User objects, where each User object has List of Pet objects. For example:

public class User {

    public String name;
    public List<Pet> pets;

    ...
}

What is the best way to query the DB to get this result?

AL.
  • 36,815
  • 10
  • 142
  • 281
dors
  • 5,802
  • 8
  • 45
  • 71
  • What's the problem/concern? Because it seems a combination of [loading users from a list](https://firebase.google.com/docs/database/android/lists-of-data#child-events) and then [joining in the pets](http://stackoverflow.com/q/31670234) (or [one of these](http://stackoverflow.com/search?q=%5Bfirebase%5D%5Bandroid%5D+join)). If you're worried about the join performance, read [my answer here](http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786). – Frank van Puffelen Feb 01 '17 at 15:35
  • Thanks @FrankvanPuffelen, my concern is this: what I want is a list of User objects (as shown in the question). Say for example I have 100 users, does it mean that I need to do a query for the users, and then loop and for each user make another query (100 queries)? And then I will need to set each User's pets list by my self... This just seems complex and inconvenient – dors Feb 01 '17 at 21:26
  • If you want to display 100 users and use an indexed data structure, you will need to get 100 items. It is a client-side join operation, which indeed leads to more client-side code. But it's not as slow as you may think, as explained in the last link in my first comment. – Frank van Puffelen Feb 02 '17 at 04:11
  • Got it. I was was afraid that this was the answer :) Thanks – dors Feb 02 '17 at 06:46

1 Answers1

0

You first need a query, considering you have the FirebaseDatabase instance

databaseQuery = firebaseDatabase.child("users").child("user1").orderByChild("name");

If you want to read more about how the common SQL queries are performed in Firebase, you can read it here Common SQL Queries Converted for Firebase

Then By using FirebaseUI, you can display the data the way you want.

To map firebase objects to your POJO, I have used FirebaseUI

 adapter = new FirebaseRecyclerAdapter<POJOClass, CustomVH>(POJOClass.class, R.layout.your_layout_file, CustomVH.class, databaseQuery)
    {
        @Override
        protected void populateViewHolder(final CustomVH viewHolder,final POJOClass model, int position)
        {
            viewHolder.setListItemTitle(model.getItem());
            viewHolder.setListItemCategory(model.getCategory());
            viewHolder.setImageView(model.getDownloadImageUrl(),getContext());
        }
    };
    recyclerView.setAdapter(adapter);

And my ViewHolder class as :

public class CustomVH extends RecyclerView.ViewHolder {
private final TextView listItemTitle;
public CheckBox checkBox;
private final TextView listItemCategory;
private ImageView imageView;

public CustomVH(View itemView)
{
    super(itemView);
    listItemTitle = (TextView) itemView.findViewById(R.id.listItemText);
    checkBox = (CheckBox) itemView.findViewById(R.id.checkBoxListItem);
    listItemCategory = (TextView) itemView.findViewById(R.id.listItemCategoryText);
    imageView = (ImageView) itemView.findViewById(R.id.customMyBucketListItemImage);
    deleteButton = (ImageButton) itemView.findViewById(R.id.listItemDeleteButton);
}

public void setListItemTitle(String name)
{
    listItemTitle.setText(name);
}

public void setListItemCategory(String category)
{listItemCategory.setText(category);}

public void setImageView(String imageUrl, Context context)
{
    //set your imageview
}
}
sagar
  • 379
  • 4
  • 13
  • Thanks, but I don't see how this answers my question about joining tables in FB – dors Feb 01 '17 at 21:27
  • There are no tables as such in Firebase . [This](https://firebase.google.com/docs/database/web/structure-data) will help. – sagar Feb 02 '17 at 00:51
  • I was hoping for an operation that can be done on FireBase's side, but I understand that it is not possible. In any case, my question is about FireBase with Android and turning the response into Java POJOs in the easiest way (not what your answer refers). Thanks anyways – dors Feb 02 '17 at 06:49
  • @dors Please check my updated answer, FireBase with Android and turning the response into Java POJOs in the easiest way – sagar Feb 02 '17 at 09:14
  • I really appreciate your efforts in trying to answer this question, but please review it again. My question does not refer to trivial Firebase queries of a specific object and then presenting it in a RecyclerView, but it refers to doing something similar to an SQL DB's join in the simplest way possible using Firebase. I understand now that it is not possible to do a "join" in the query level and that I need to perform several queries to perform it, and that is the answer to my question – dors Feb 03 '17 at 09:12