3
votes

I am trying out firebase database and I was checking the recommended way of modeling many to many or one to many relationships.

Say I have this relationship between post and user: user has many posts.

This is my approach for the model design:

class User{

List<String> postIds;

...
}

class Post{

String userId;

....
}

This is according to the firebase documentation here.

I like the design instead of embedding posts created by a user under user collection like the mongodb style this design is flat; so later time if we want to fetch only users on the system we dont have to pull the posts under the users as well.

But my doubt with this design is even embedding the ids within the posts could be a problem later on; imagine I have 100 users with 1000 posts each. If I want to show list of users I have to pull 100 users which means I have to pull 100,000 post ids.

Is there any lazy loading concept on firebase? ie when I fetch a user entity the postIds should not be loaded automatically; it should be loaded on demand.

2

2 Answers

2
votes

There is no "lazy loading" or "load on demand" construct present in Firebase at the moment. All the data under a location is read and transferred on access. One thing you can do is separate out the User and UserInfo to two different branches so you can access users separately without pulling in the excessive data.

class User {
  String id;
  String name;
  String gender etc.
}

class UserInfo {
  List<String> postIds;
  Other info maintained per user
}

In this way, you can read the users without pulling extra information.

0
votes

An important rule in Firebase is to have the data as flatten as possible. You can take a look at this post, Structuring your Firebase Data correctly for a Complex App, for a better understanding.

Because there is no way in the Firebase Database to download just one property of each node, the single way to achieve this is to use a new node that hosts all those ids. So if you want an efficient way to verify the existens of an id or to count all the users, download just the list of ids. For good measure you should keep precisely that list of ids in the database.

To get all those ids, you can use this code:

DatabaseReference postRef = FirebaseDatabase.getInstance().getReference().child("Post");

postRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot ds : dataSnapshot.getChildren()) {
            String uId = ds.getKey();
            Log.d("TAG", uId);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
    throw databaseError.toException(); // don't ignore errors
    }
});

Hope it helps.