Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data Modeling Best Practices in Firebase/AngularFire

I'm developing an application in Firebase for the first time and was curious how I should model the data between two objects, a user and a post. I come from more of a relational db background and was curious not only how this would be done in nonrelational DBs but specifically how to set up a relationship between two objects in Firebase.

For example, my application has many Users, and each user creates many Posts.

User {
    firstName: String,
    lastname: String,
    userName: String
}

Post {
    title: String,
    content: String,
    date: Date,
    writtenBy: [User object?]
}

How should I structure these two objects in Firebase so that a Post belongs to a User, but all Posts can be queried for regardless of User, and both User and Post objects can be edited without disrupting the other object's data and/or relationship?

And how should I create new "relational" objects via firebase:

sync.$set({userA: {
   firstname: "Billy",
   lastName: "Bob",
   userName: "BillyBob",
   Posts: {
       // .....
   }
}
});

Thanks!

like image 571
reknirt Avatar asked Jan 11 '23 01:01

reknirt


1 Answers

Firebase is built with performance in mind. This is the reason you have to design data structures differently, normalization is your enemy in most cases. Every object in Firebase can be accessed by URL, and you should always keep this in mind. There are still many ways of designing the data structures, it depends on what queries do you want to execute. If one of the queries is to be able to display all messages (I believe a number of latest messages would be the most common use case), but at the same time you want to be able to show messages per user than one of the possible data structures could look like this:

User {
    userId(assigned by Firebase automatically) {
        firstName: String,
        lastname: String,
        userName: String
    }
}

Post {
    User {
        userId(matching userId in the User object) {
            postId(assigned by Firebase for every new post automatically) {
                title: String,
                content: String,
                date: Date,
                writtenBy: String, userName or userId (this is not really needed, but may keep it for easier data access)
            }
        }
    }
}

Then you can change any user data without triggering data change events in Posts, like in your example, (which would be extremely heavy if you have large number of messages). You can get all messages independently of user:

var postListRef = new Firebase(URL);
var lastPostQuery = postListRef.child("Post").limit(500);

You can also use startAt() and endAt() quesries https://www.firebase.com/docs/web/api/query/limit.html As a drawback - you have to unpack every message in the for loop if you need to show only messages, but I would expect you would show user info as well, so it should be ok.

If you want to listen for just one user messages, it's very simple and fast:

var postListRef = new Firebase(URL);
var lastPostQuery = postListRef.child("Post/User").child(userId);

And Angular/AngularFire has great support for this kind of data structures.

like image 92
Alexander Burakevych Avatar answered Jan 19 '23 01:01

Alexander Burakevych