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!

Create a real time shared sticky notes application with Login/Signup using just front-end and firebase!

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. 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. <script type="text/javascript" src="https://cdn.firebase.com/js/client/2.2.3/firebase.js"></script> Here is the HTML code that I am using - <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description"> <meta name="author"> <title> Realtime Shared Sticky Notes Using Bootstrap and Firebase </title><!-- Bootstrap core CSS --> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" type="text/css"><!-- Custom styles for this template --> <link href="starter-template.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script> <link href="assets/css/sh-default.css" rel="stylesheet" default-stylesheet="true" type="text/css"> <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"> </head> <body style="cursor: auto;"> <div class="navbar navbar-inverse navbar-fixed-top" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button><a class="navbar-brand" href>Realtime Shared Sticky Notes</a> </div> <div class="collapse navbar-collapse"> <ul class="nav navbar-nav pull-right"> <li> <a data-target="#login" href>Login</a> </li> <li> <a data-target="#register" href>Signup</a> </li> <li> <a data-target="#lists" href>Shared List</a> </li> <li> <a id="logout" href>Logout</a> </li> </ul> </div><!--/.nav-collapse --> </div> </div> <div class="welcome"></div> <div class="container tab default" id="login"> <form class="form-signin" role="form"> <h2 class="form-signin-heading"> <em class="stackhive-marker"></em>Login to your account </h2> <hr> <input type="email" class="form-control" placeholder="Email address" required="" autofocus="" id="login-email"><input type="password" class="form-control" placeholder="Password" required="" id="login-password"> <button class="btn btn-primary" type="button" id="login-btn"> Login </button> <hr> <div class="status alert alert-info hide"></div> </form> </div> <div class="container tab hide" id="register"> <form class="form-signin" role="form"> <h2 class="form-signin-heading"> Register a new account </h2> <hr> <input type="text" class="form-control" placeholder="Your Name" required="" autofocus="" id="name"><input type="email" class="form-control" placeholder="Email address" required="" autofocus="" id="email"><input type="password" class="form-control" placeholder="Password" required="" id="password"> <button class="btn btn-primary" type="button" id="signup-btn"> Sign Me Up! </button> </form> <hr> <div class="status alert alert-info hide"></div> </div> <div class="container tab hide" id="lists"> <div class="status alert alert-info hide"></div><br> <h3> Add Items to the Shared List </h3> <p> <textarea type="text" id="listitem" placeholder="Add content that you want to add to your list"></textarea><br> <a id="addItemToList" class="btn btn-success">Add it to your list</a> </p> <hr> <a class="btn btn-info" id="sort-items">View Aligned (for OCD fellows!)</a> <ul id="sharedlist" class="sharedlist" data-widget-class="sharedlist"></ul> </div><!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> <script type="text/javascript" src="https://cdn.firebase.com/js/client/2.2.3/firebase.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script> <script type="text/javascript" src="./firebasefunctions.js"></script> </body> </html> 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/<auth.uid>/ 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}