Friday, January 4, 2013

Build your own social network

A Little History :
There was a time, I dreamed about me, writing a social network, and launching it. Soon, I realized, I don't know HTML, I don't know CSS, I don't know what JS is, and of course, I don't know a single scripting language. (Of course, I could write simple programs in other languages like C/C++, Java)
But I hadn't ever built something this big.

HTML was fun, I learned it quickly (Come on, who can't?), CSS was a bit tricky though, it took a few days to figure out what stands for what actually.

And then came the core-programming language of the site : PHP. I enjoyed it, I found many people criticizing it all over the Internet, but I loved it (Maybe, I haven't gotten in the problems yet, they have)

^ This all happened last year.

 Now the-real-thing :
This semester, I had to work on a website, something dynamic! There were topics like student database management system, library management system, online ticket booking, exetra, exetra!
So the dream of mine came to my mind again, a social networking site! And it took no time to finalize the topic. I was pretty happy that I was going to build a social networking site. I had no single idea how I was going to do that ( I hadn't built a single website before )
The thing is that, I hate working on the front end/UI. It takes a LOT of time to trial and error. Switch to your editor, back to your browser, back to your editor, and on and on... I just hate it. And I don't feel like I've used enough brain. It's more like – hardwork.
So I chose a guy in the class, who was willing to work on the front end, and I was happy that somebody is willing to work on it, so I'll have my freedom to work on the back-end. In next few days, we totally forgot about we have a big thing to work on, in this semester.
And then, suddenly, came our HOD, with a notice.. kind of a deadline to our projects.. WE WERE TERRIFIED!

So what challenges I faced?
  1. The thing is that we both were n00bs, and had no idea of anything. We were working together. While building a website, it is required to have the front end/UI ready before starting to work on the back end. Now I had no front end, so I built a 'temporary-template' to get me working.
  2. Now that I had some temporary-template to start working with, I had no idea of the database schema. I didn't know how to build it. Of course, I'd learned how to design it, but there was nothing about social networks in the book. I had to think.
           Then after referring some systems, I could think how it could go..


  • First, I got this `users` table on the paper :

Here, what it looked like : 

userID       PK

Next was the `posts` table, where I was going to save the things posted by the users
postID PK
userID FK
Now I thought, yeah, this is pretty easy! (I hadn't thought about `friends` thing yet)

  • Relations! Relations!! Relations!!!

God, how can I save in the database, user 'x' has 3 friends, and they are a, b, and c? This is where I was stuck for like a day!
I simply drew `friends` a table like this :

friendID PK
userID FK

Now, I was feeling a bit odd about inserting two entries for the same relation (I, still do).
But anyway, at-least I've found a working solution.

  • There was a next challenge, where to save the 'friend request', and how to work with it..
So I built a new table, `friend_requests`
requestID PK

as simple as that! Now, I could save friend requests sent in this table, if “toUserID” accepts the request, I would delete the entry from this table and insert a new row in `friends` table!

I was a bit happy now. At least, I could let users send friend requests, accept them, reject them, post new things to their account and let their friends see it at their home page! (Oh, I didn't mention how it'd work)

So, basically, when user logs in, I check his/her friends from `friends` table. I get all their userID's in an array, and again, make a new query to get all the posts, from the `posts` table according to their userIDs. And I'll show all these posts to the user. Simple. Also, I had to let users comment on the post, and the 'like' thing, too! It was easy, I created two new tables, `comments`, and `likes` they're as follows :

commentID PK
userID FK
likeID PK
postID FK
userID FK

I'd retrieve entries as per posts from these tables, too

  • Now there was a BIG challenge! Messages!
I don't know how I did it, but, I guess, it was the most hard thing in this project. I am gonna show you how this works.
I wanted it to look like inbox in our phone. Once you open up the “messages”, you should get to see the last conversations you had, with last message in front of the user you were talking with, and the time!
So, I built two tables for it. First, message records, to save the entries of other users, x user had conversations with, and in `messages` table, I'd save the conversationID (from message_entries), senderID, and receiverID. ConversationID makes it easy to retrieve all messages of a single conversation from the table. Check tables below, you'll get the idea!

convID PK
user1ID FK
user2ID FK

messageID PK
convID FK
senderID FK
receiverID FK

Again, message_records has only one entry for one conversation. Suppose user X sends a message to user Y for the first time, I create a new entry in message_records, and get the convID to save further messages in the `messages` table. This is for the first time only. Next time, if user Y sends a message to user X, we will use the same convID to save his message in the `messages`.

So, now, I could build the basic functionalities.. And I built it in 3 days, and 3 nights. I used to take 4 or 5 hours sleep in these days. I worked pretty hard, but the result was great. This thing was working!

Then came the nightmare! I had totally forgotten about the primary thing about this site!
I'd given an unique feature in the synopsis of this project – Public & Private networks!
 " What's that? "
I was a facebook user (yes, I don't use it anymore). And the thing, I most hated about facebook was its news-feed, which would cram all those posts by applications, by pages, by friends, in a single narrow vertical bar. Most of the times, I'd lose an important post of my friend. I didn't want this thing in my site. And so, I'd found a solution on it. I created two 'networks' for each user. First, private, and second, public. Basically, you once you sign up with this site (er, it's not live, I am just telling you the idea) you get those two 'networks'. In private, you will get to see things posted by your friends only. And in public, there will be posts by 'pages', groups, applications (we don't have last two things yet)..

So, I was terrified by knowing that I don't have 'pages' stuff in this site yet! But it wasn't as hard as what I'd built up till now. To create a new page, one have to be a user of this site. One can create either a celebrity page, or a corporate page. I wrote a `pages` table in which, I could save all the details about that page. The one who create a page, would be the owner of that page, and he will have this page “liked” by-default! Also, only owner can post on this page. Only owner gets to see the 'share-box' on this page, others will see a “like” button, and if it's already been liked, an “unlike” button would be there.

So how all this work?
There is a `pages_likes` table in which, I save which user has liked which pages :

userID FK
pageID FK

Then I'd retrieve this list whenever user clicks 'public' button above his news feed, and retrieve posts from `page_posts` and show them in the news feed of the user.
Nice hun? No more crap in between posts of your best friends, family members, or whoever you're friends with.. :)

Below, are some screen-shots of this site (which is currently on my laptop)

The login screen

 The "share-box"

Home page, and the "news-feed"

The profile page

    Thanks for taking time and reading this post. If you are interested in the project, the source code is available at GitHub. :)