You are here: Home » NewsFeeds » Building Trello using Firebase in 2 hours!

Building Trello using Firebase in 2 hours!

Firebase is an incredibly powerful cloud based real-time database that allows you to store and sync data without diving into back-end coding at all.

“You can save data, update data, and listen for data changes in realtime with only a few lines of code. Data is stored as standard JSON and is accessible from any platform.” – Firebase

In this post, I’ll be going over Firebase and how it can abstract away a lot of things while allowing you to focus on your front-end development. I’ll be building a Real Time Shared Sticky Notes App using Firebase. So let’s get this party started!

Getting Started With Firebase

To get started with firebase, you need to signup and create your app. They have a free plan so you can try it out without any hassles.

Once you have created an app, you’ll get a unique url for it – xxxxxxxxxxxx.firebaseio.com/

This url is your key for all the API calls to your app.

Enabling User Login and Auth

Login and Auth Settings allows you to create login/signup for your application. The quickest way to get started is via Email & Password login. You can enable it from your app’s dashboard.

Firebase Dashboar | Login and Auth Section

You can even set up password reset emails and content from here!

Once you have enabled Email & Password Authentication, you are good to go and dive into linking Firebase to you HTML pages.

Note – You can allow users to Login via Facebook, Twitter, Github and Google as well. For this app, I’ll be setting up Email/Password Auth only.

Linking Firebase to Login/Signup Forms

At this point you should have your HTML/CSS done and should have 2 forms for the users to register and login to their accounts. I used StackHive to build from the browser, obviously! 🙂

To begin with Firebase you just need to include their JS file.

		
		

Here is the HTML code that I am using –



    
        
        
        
        
        
        
            Realtime Shared Sticky Notes Using Bootstrap and Firebase
        
        
        
        

        
        
        
    
    
        
        

First thing we need to do is instantiate our Firebase reference.

var firebaseref = new Firebase("https://dazzling-fire-8954.firebaseio.com/")
		

Let’s connect Firebase with our login form. Firebase has a direct API call for authenticating using Email and Password – authWithPassword({},callback).

$("#login-btn").on('click', function() 
{
        var email = $("#login-email").val();
        var password = $("#login-password").val();
        firebaseref.authWithPassword({
            email: email,
            password: password
        }, 
        function(error, authData) {
            if (error) {
                console.log("Login Failed!", error);
            } else {
                console.log("Authenticated successfully with payload:", authData);
            }
        });
});
		

Similarly, we connect our signup form as well using the createUser({},callback) API call –

$("#signup-btn").on('click', function() 
{
	var email = $("#email").val();
	var password = $("#password").val();
	firebaseref.createUser({
		email: email,
		password: password
	},function(error, userData) {
		if (error) {
			console.log("Error creating user:", error);
		} 
		else {
			console.log("Successfully created user account with uid:", userData.uid);
			//additionally, you can log the user in right after the signup is successful and add more data about the user like name etc.              
		}
	});
});
	

So far we have set up our login and signup forms. For a user to log in, they’ll need to go through the login form every time! Hence, we need to identify if the user is already logged in and update the app accordingly.

In order to detect any changes in the login state of a user, Firebase has onAuth(callback) API call that is triggered every time a user logs in or out.

//Callback for Auth Changes
var authDataCallback = function(authData) 
{
        //authData is the object sent by Firebase in the callback.
        if (authData) {
            console.log("User " + authData.uid + " is logged in");
        } 
        else {
            console.log("User is logged out");
        }
}

//register a callback for the change in Authentication Status
firebaseref.onAuth(authDataCallback);

		

Now, whenever a user logs in or out, authDataCallback will be called. This function will also be triggered if you refresh the page and hence the user can remain logged in (till the browser session is active).

So our login/signup is almost complete. Before we move forward, we need to look into Firebase Rules –

Firebase Security Rules

Firebase rules are a way for restricting and securing the data. You can control the read and write permissions for any node of the data. Each node is essentially a url like –
xxxxxx.firebaseio.com/users/1001/name

The above url represents the name of a user with an id as 1001. We need a way to restrict who can read or write data to this url. Firebase Rules do exactly that.

For more details and understanding of the security rules – check out https://www.firebase.com/docs/security/guide/understanding-security.html

Note – This is a really important part of firebase and you’ll need to go over them in details before launching your app!

For this application, I have the following rule structure set up –

{
  "rules": {
	"users": {
	  "$uid": {
		// grants write access to the owner of this user account whose uid must exactly match the key ($uid)
		".write": "auth !== null && auth.uid === $uid",
		// grants read access to any user who is logged in with an email and password
		".read": "auth !== null && auth.provider === 'password'"
	  }
	}
  }
}
		

Users node is used to save the data about each user with their uid as the key.

My users node is only readable by a user who is logged in using a password.
The node is only writable by the user who has the same uid (hence only the user can change content of his node. The node will contains profile data for of the users.)

“This rule grants a user write access on /users// to the user whose unique ID matches the dynamic path, $uid.” – Firebase

Once your rules are setup, your login/signup system is ready.

Getting Started on Shared List -Saving Data and Firebase Events

Next up is setting up a shared list where the users can create/delete items.

The rules for my list are –

"lists":
{
	   // grants write access to any user who is logged in with an email and password
		".write": "auth !== null",
		// grants read access to any user who is logged in with an email and password
		".read": "auth !== null && auth.provider === 'password'"
}
		

There are 3 events that are available in Firebase which help in creating a real time app effortlessly!

    Lets set up these events to listen for the changes on the shared list –

    var setUpFirebaseEvents = function() 
    {
        listRef = new Firebase('https://dazzling-fire-8954.firebaseio.com/lists/sharedlist/items');
        $("#sharedlist").html('');
        listRef.off('child_added', childAddedFunction)
        listRef.on("child_added", childAddedFunction);
    
        listRef.off('child_changed', childChangedFunction);
        listRef.on('child_changed', childChangedFunction);
    
        listRef.off('child_removed', childRemovedFunction);
        listRef.on('child_removed', childRemovedFunction);
    }
    var authDataCallback = function(authData) 
    {
        console.log("authCallback Event is called from onAuth Event");
        if (authData) {
            console.log("User " + authData.uid + " is logged in with " + authData.provider);
            setUpFirebaseEvents();
    
        } 
        else 
        {
            console.log("User is logged out");
        }
    }
    	

    We call the setUpFirebaseEvents function from the authDataCallback. Here are the callback functions for each event to handle the changes –

    var childAddedFunction = function(snapshot) {
        var key = snapshot.key(); //return the key for the item
        var listItem = snapshot.val(); //returns the value of the item as JSON
        console.log("Key - " + key + " has been added");
        buildNewListItem(listItem, key); //adds the new item to the list
        $("#lists .status").fadeIn(400).html('New item added!')
    }
    var childChangedFunction = function(snapshot) {
        var listItem = snapshot.val();
        var key = snapshot.key();
        console.log("Key - " + key + " has been changed");
        updateListItem(listItem, key); //updates the position of the item
    }
    var childRemovedFunction = function(snapshot) {
        var key = snapshot.key();
        removeListItem(key); //remove the list item
        console.log('Child Removed');
    }
    	

    Note –
    key = snapshot.key(); – This return the key at which the element is stored in firebase.
    In terms of url – dazzling-fire-8954.firebaseio.com/lists/sharedlist/items/{key}

    Saving Data to Firebase

    There are 4 ways to save data to firebase –

    • Set()
    • Push()
    • Update()
    • Transaction()

    To learn more about each of them in detail check out the documentation at – https://www.firebase.com/docs/web/guide/saving-data.html

    In this application, I have used push() to add list items to the items node, and update() to add the position changes after a user drags the item around.

    set() function replaces the node while update() only change the node.
    push() creates a unique key for the item.

    In this case, each item is pushed to
    dazzling-fire-8954.firebaseio.com/lists/sharedlist/items/uniquekey/

    I have divided the tasks into 3 functions that work on the shared list –

    • buildNewListItem(listItem,key)
    • updateListItem(listItem,key)
    • removeListItem(key)
    var buildNewListItem = function(listItem, key) 
    {
        var author = listItem.author;
        var content = listItem.content;
        var timestamp = listItem.timestamp;
        var id = key;
        var css = listItem.css;
        var $newListItem = $("
  1. ").html("

    Added By - " + author + " " + " on " + timestamp + "

    " + content + "

    "); $newListItem.prependTo($("#sharedlist")); $newListItem.attr('style', css); //$("#sharedlist").prepend($newListItem); bindEventsToItems($newListItem); // this function makes the item draggable and adds the remove button event. You can extend this function to create more functionality. } var updateListItem = function(listItem, key) { var author = listItem.author; var content = listItem.content; var timestamp = listItem.timestamp; var id = key; var css = listItem.css; $("#lists [data-item-id='" + id + "']").attr('style', css); } var removeListItem = function(key) { $("#lists [data-item-id='" + key + "']").remove(); }

    So far, we have added all the handlers to manage any changes in the list. Only thing left is to link our form to create new list items and save them to firebase.

    var addListItem = function(content) 
    {
        var postsRef = listRef;
        var x = Date();
        var random = randomIntFromInterval(1, 400);
        var randomColor = getRandomRolor();
        var topzindex = $("#sharedlist li").getMaxZ() + 1;
        $temp = $("
  2. "); $temp.css({ 'position': 'absolute', 'top': random + 'px', 'left': random / 2 + 'px', 'background': randomColor, 'z-index': topzindex }); var css = $temp.attr('style'); try { var newItemRef = postsRef.push({ author: userData.fullname, content: content, timestamp: x, css: css }); //child_added event will be triggered on all the open instances } catch (e) { $("#lists").find(".status").html(e); } }

    The addListItem function creates the item and pushes it to firebase.

    Note that we are not inserting the item to the page from here. As soon as you “push” the item to firebase, the child_added event is triggered and takes care of adding the element to the list. This makes the real-time part of the app possible!

    Similarly, we use the remove() and update() api calls to bind the functionality –

    var removeItemFromFirebase = function(key) {
        var itemRef = new Firebase('https://dazzling-fire-8954.firebaseio.com/lists/sharedlist/items/' + key);
        itemRef.remove();
       //child_removed event will be triggered on all the open instances
    }
    
    var addCSSStringToItem = function(key, css) {
        var itemRef = new Firebase('https://dazzling-fire-8954.firebaseio.com/lists/sharedlist/items/' + key);
        itemRef.update({
            css: css,
        });
       //child_changed event will be triggered on all the open instances
    }	
    	

    You can easily extend this code to create a real time chat application (with just a few minor UI changes) or even build your own custom Trello (a tasklist management system)

    I used StackHive + Firebase to create the app from the browser directly and it worked perfectly! Browser based development in general pairs up very nicely here!


     

    Original article