From SQL to Firebase — How to structure the DB for a social network app

Gil Goldstein
3 min readJul 18, 2016

--

Note: I am not a Firebase expert, I just got into it while working on an iOS app. I write this article after struggling to find a way to implement some core social network app concepts such as “posts”, “likes”, “followers” and so on.

Introduction

As someone who used to work with SQL databases, switching to Firebase’s realtime database model was extremely weird.

I base allot of the information here on this post on the Firebase blog: https://firebase.googleblog.com/2015/10/client-side-fan-out-for-data-consistency_73.html?m=1

The basic concept

Firebase doesn’t use tables, rows and columns. Instead they use a big JSON file that has “nodes”. You write \ read data by supplying the path to the node you want.

Like the post on the Firebase blog mentions, you need “fanout” your data to multiple locations in the JSON for easier read access.

The concept is strange to someone who is used to SQL. In SQL you simply reference a key to a key in another table. In Firebase you have to duplicate the data to all the locations you need.

So for example, if your app uses hashtags in posts and you want the ability to show all posts for a specific hashtag, you will also have to duplicate each post a user submits to a “hashtags” node under each hashtag’s sub node.

Hashtags: {
<hashtag_id>: {
name: "MySuperCoolHashtag",
posts: {
<post_id_1>: {
// your post data
},
<post_id_2>: {
// your post data
}
}
}
}

What about Likes?

Likes are handled similarly to posts. You need to keep a record of the “like” all the places you may need to use it, for example: viewing the list of people who liked a post or a “Notifications” section where a user sees who liked his posts.

To accomplish those 2 examples you will need a node structure like this:

PostLikes: {
<post_id_1>: {
<user_uid_1>: true,
<user_uid_2>: true,
...
}
},
Notifications: {
<user_uid_1>: {
<notification_id_1>: {
from_user: <some_user_uid>,
type: "like",
for_post: {
<post_id>: {
// your post data
}
// add whatever else you need to know about this notification.
}
}
}
}

The above notifications structure also allows you to store other types of notifications, not just “like” alerts, for example “comments” or “friend requests”.

How to count Likes \ Comments?

Firebase lets you count the number of children in a node by using:

snapshot.children.count

but when you have allot of data this may not be the best approach. Instead you should keep a “counter” in your posts node under each post id.

When creating a new post, set the value to 0. When someone likes a post, increment the counter by 1.

You can use Firebase’s “Transactions” to do this.

Follow Functionality

For handling a “followers” type functionality, you will need at least 2 separate nodes: “followers” and “following”.

Separating the follower-following relationship into 2 separate nodes helps with accessing this data when you want to get the list of followers for a user or a list of who this user is following.

Just as with posts, when a user follows someone, you need to update this user’s following node and the target user’s followers node.

Conclusion

As you can see, in Firebase, data duplication is key for handling data in different ways. Think of a node in the db as a “View” in your app. If your app needs to display some data in a certain way in one place and another way somewhere else, that means you need to duplicate your data to multiple nodes.

Like I mentioned, this sort of thinking goes against everything we know about SQL but this way makes sense in Firebase, as “write” operations are considered cheap and “read” is more important to provide your users fast access to data.

I hope this post helps you, if you have any questions or if you are doing something differently please share it with me in the comments!

--

--