[Updated] Intro to Firebase with JavaScript and jQuery

Firebase with JavaScript and jQuery
Hey! How are you all? It had been a while since last post. Today we will go through an intro to the Firebase with JavaScript and jQuery. Here we will cover Firebase and its working with basic JavaScript and jQuery. And in the meanwhile we will create a basic contact store app using these.

Firebase?

Firebase, now part of Google, is a Cloud Services Provider for Backend as a Service. They provide realtime database for the App Development on the various platforms through APIs.

Why do we need Firebase or Similar System?

You might have gone through the time consuming task of getting a database ready and then synchronizing data on the application for all users. And if the application is spanning to multiple platforms along with multiple user, I can assume a lot of time spent in preparing the Realtime and Synchronous state of the system.

So if you have a online DBMS, it will save you from setup and getting started time.

And if you have realtime communication API, it will save you from the effort to figure out an architecture and system design to do the same.

Now if these above two thing are available in one, what else do we need?
Within no time you can make a Good, Logical, Thoughtful Idea to an Awesome working Idea.

And for a plus, if that DBMS already provides you the very common authentication schemes, Icing on the Cake. Within a small development time your Awesome Idea became an WOW! What an Idea!.

So enough with the praises; lets come to “Getting Started with Firebase” thing.

First you need to signup at Firebase. For this you can go to https://console.firebase.google.com/ directly and finish the signup.

As soon as you sign-up/log-in, you will see account dashboard and here you can create a new app.

Click on Add Project button similar to this


Enter the project details and click Create Project

As soon as the App creation finishes, firebase console will redirect to App management section.

Now we have an app URL, we can develop our app at front end and use the API to do the CRUD operations. As we are going to use JavaScript to access Firebase Real Time Database, we can get the necessary code to enable Firebase in our JavaScript/Web App by following the steps shown in the following pictures:


Dashboard; Click on Add Firebase to your Web App


Copy config; Click on Copy to copy the config

Above copied code can be pasted in the HTML file just above the script tag for our bindings file script.js.

Another way can be that we include the necessay firebase script as:

<script src="https://www.gstatic.com/firebasejs/4.5.0/firebase.js"></script>

And then initialize the firebase in our script.js like as follows:

// file: script.js
// Initialize Firebase
var config = {
  apiKey: "...",
  authDomain: "...",
  databaseURL: "...",
  projectId: "...",
  storageBucket: "...",
  messagingSenderId: "...."
};
firebase.initializeApp(config);
// ... rest of the code

As our app is initialized, we can create the database reference through which we will be doing our Read and Write operations.

But before proceeding, it always to have a little idea/plan about structure of the data being stored. As the data is stored in the JSON format, lets use the following data organization/structure for our DB:

"contactdb" : {
  "contacts": [{
    "contactId": {
      "name": "Time to Hack",
      "email": "the.time2hack@gmail.com",
      "location": {
        "city": "Internet", // can be real city ;)
        "state": "Active Connection", // can be another state
        "zip": "000000" // can be anything else
      }
    }
  }]
}

As from above format it is clear that out db has child array contacts. This array will hold the contact objects as a key value pair of contactId and contactObject. contactId is a hash generated by Firebase. Hashed are used to prevent the concurrent access and overlapped data writing.

Actual object will look like this:

{
  "contacts" : {
    "-Jl4Y4ek1Gpb1dLW9R8o" : {
      "email" : "pankaj@time2hack.com",
      "location" : {
        "city" : "Gurgaon",
        "state" : "Haryana",
        "zip" : "122001"
      },
      "name" : "Pankaj Patel"
    },
    "-Jl9cQXgm_6YkdC1xgCK" : {
      "email" : "pankaj@pankaj.pro",
      "location" : {
        "city" : "Gurgaon",
        "state" : "Haryana",
        "zip" : "122001"
      },
      "name" : "Pankaj Patel"
    }
  }
}

Lets come back to the app design. For the basic things we must be able to add and view data.

Firstly we will see how to add data. As we have already created the reference to our db; we can now create a reference to the child array contacts by the ref() method. To get the new reference of child object, following is the code:

var dbRef = firebase.database();
var contactsRef = dbRef.ref('contacts');

Now as we have the reference to the child array contacts; we can push (as the object is an array) the contact object to add into this array by following code:

contactsRef.push({
  name: 'Time to Hack',
  email: 'thetime2hack@gmail.com',
  location: {
    city: 'The Internet',
    state: 'The Internet',
    zip: '127.0.0.1'
  }
});

And the contact gets added to the Firebase App. Now there is a trigger to an event of child_added which will get the newly added child.

As we are working with the collection contacts we are having events child_added, child_removed and child_changed. child_moved event is also there but available only when working with the ordered data.

value event can be used for addition and changes in the data but will provide everything. So in case of collection value callbacks can take longer time to execute because of large dataset received. But for collection, can be used for first load of app.

For viewing or reading of all contacts, following code can be used. But to loop over the contacts collection we need to work with the Firebase collection iterator forEach. Following code will demonstarte this:

contactsRef.on("child_added", function(snap) {
  console.log(snap.val())
  snap.forEach(function(childSnapshot) {
    var key = childSnapshot.key();
    var childData = childSnapshot.val();
  });
});

So with above code we completed the C(Create) and R(Read) of the CRUD operations of our application.

Now for U(Update) and D(Delete) we can use .set() and .remove() methods. While updating data, we would need to travarse to particular key child object anf then use set method, the set method accepts new updated object to be set as new value. And after travarsal if you wanna delete that node/key, you can use the .remove(). Following is the example code for adding, updating and then removing a rogue/improper value.

contactsRef.push({
  "email" : "wrongemail@gmail.com",
  "location" : {
    "city" : "Gurgaon",
    "state" : "Haryana",
    "zip" : "122001"
  },
  "name" : "Pankaj Patel"
})
contactsRef.on("child_added", function(snap) {
  //set the new value after 10 seconds
  setTimeout(function () {
    contactsRef.child(snap.key()).set({
      "email" : "morewrongemail@gmail.com",
      "location" : {
        "city" : "Mumbai",
        "state" : "Maharashtra",
        "zip" : "452001"
      },
      "name" : "Pankaj"
    });
  }, 10*1000);

  //delete the object after 20 seconds
  setTimeout(function () {
    contactsRef.child(snap.key()).remove();
  }, 20*1000 );
});

So till now we went through all CRUD operations with our Firebase Data. Let’s put all bricks together to shape our contacts store application. To build a quick and easy UI, we are using Twitter Bootstrap here. You can also go through the Getting Started article of Twitter Bootstrap at Time to Hack. Following is the HTML for Form to add contact data and List of Contacts:

<!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">
  <title>Time to Hack: Firebase with JavaScript and jQuery</title>
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
  <style type="text/css"> #contacts p, #contacts p.lead{ margin: 0; } </style>
</head>
<body>
  <div class="container">
    <h1>Contact Store Application</h1>
    <hr/>
    <div class="row">
      <div class="col-md-6">
        <form method="post" name="contactForm">
          <div class="form-group">
            <label for="name">Name</label>
            <input type="text" class="form-control" id="name" required placeholder="Enter name">
          </div>
          <div class="form-group">
            <label for="email">Email</label>
            <input type="email" class="form-control" id="email" required placeholder="Enter Email">
          </div>
          <h3>Location</h3>
          <div class="form-group">
            <label for="city">City</label>
            <input type="text" class="form-control" id="city" placeholder="Enter City">
          </div>
          <div class="form-group">
            <label for="email">State</label>
            <input type="text" class="form-control" id="state" placeholder="Enter State">
          </div>
          <div class="form-group">
            <label for="zip">Zip</label>
            <input type="text" class="form-control" id="zip" placeholder="Enter Zip Code">
          </div>
          <button type="submit" class="btn btn-primary addValue">Submit</button>
        </form>
      </div>
      <div class="col-md-6">
        <ul id="contacts" class="list-group">
          <!-- Contact Object li.list-group-item.contact will be added here by js -->
        </ul>
      </div>
    </div>
  </div>

  <!-- jQuery (necessary for Bootstrap's JavaScript plugins) and Bootstrap -->
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
  <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
  <!-- Include Firebase Library and Config-->
  <script src="//www.gstatic.com/firebasejs/4.5.0/firebase.js"></script>
  <!-- Contacts Store JavaScript -->
  <script src="script.js"></script>
</body>
</html>

And the script that will have all functionality of our app is as follows:

// file: script.js
// Initialize Firebase
var config = {
  apiKey: "AIzaSyCfolxrOcBrgxVXKiBmdRbwakCNsw-kHbQ",
  authDomain: "tempone-7869c.firebaseapp.com",
  databaseURL: "https://tempone-7869c.firebaseio.com",
  projectId: "tempone-7869c",
  storageBucket: "tempone-7869c.appspot.com",
  messagingSenderId: "557485542616"
};
firebase.initializeApp(config);

//create firebase database reference
var dbRef = firebase.database();
var contactsRef = dbRef.ref('contacts');

//load older conatcts as well as any newly added one...
contactsRef.on("child_added", function(snap) {
  console.log("added", snap.key(), snap.val());
  document.querySelector('#contacts')
    .innerHTML += contactHtmlFromObject(snap.val());
});

//save contact
document.querySelector('.addValue')
  .addEventListener("click", function( event ) {  
    event.preventDefault();
    if( document.querySelector('#name').value != '' 
          || document.querySelector('#email').value != '' ){
      contactsRef.push({
        name: document.querySelector('#name').value,
        email: document.querySelector('#email').value,
        location: {
          city: document.querySelector('#city').value,
          state: document.querySelector('#state').value,
          zip: document.querySelector('#zip').value
        }
      });
      contactForm.reset();
    } else {
      alert('Please fill atlease name or email!');
    }
  }, false);

//prepare conatct object's HTML
function contactHtmlFromObject(contact){
  console.log( contact );
  var html = '';
  html += '<li class="list-group-item contact">';
    html += '<div>';
      html += '<p class="lead">'+contact.name+'</p>';
      html += '<p>'+contact.email+'</p>';
      html += '<p><small title="'+contact.location.zip+'">'
                + contact.location.city + ', '
                + contact.location.state + '</small></p>';
    html += '</div>';
  html += '</li>';
  return html;
}

And following script is same as above, but has jQuery code instead of plain JavaScript:

// file: script.js
// Initialize Firebase
var config = {
  apiKey: "AIzaSyCfolxrOcBrgxVXKiBmdRbwakCNsw-kHbQ",
  authDomain: "tempone-7869c.firebaseapp.com",
  databaseURL: "https://tempone-7869c.firebaseio.com",
  projectId: "tempone-7869c",
  storageBucket: "tempone-7869c.appspot.com",
  messagingSenderId: "557485542616"
};
firebase.initializeApp(config);

//create firebase database reference
var dbRef = firebase.database();
var contactsRef = dbRef.ref('contacts');

//load older conatcts as well as any newly added one...
contactsRef.on("child_added", function(snap) {
  console.log("added", snap.key(), snap.val());
  $('#contacts').append(contactHtmlFromObject(snap.val()));
});

//save contact
$('.addValue').on("click", function( event ) {  
    event.preventDefault();
    if( $('#name').val() != '' || $('#email').val() != '' ){
      contactsRef.push({
        name: $('#name').val(),
        email: $('#email').val(),
        location: {
          city: $('#city').val(),
          state: $('#state').val(),
          zip: $('#zip').val()
        }
      })
      contactForm.reset();
    } else {
      alert('Please fill atlease name or email!');
    }
  });

//prepare conatct object's HTML
function contactHtmlFromObject(contact){
  console.log( contact );
  var html = '';
  html += '<li class="list-group-item contact">';
    html += '<div>';
      html += '<p class="lead">'+contact.name+'</p>';
      html += '<p>'+contact.email+'</p>';
      html += '<p><small title="'+contact.location.zip+'">'
                + contact.location.city + ', '
                + contact.location.state + '</small></p>';
    html += '</div>';
  html += '</li>';
  return html;
}

In this app, we would not go ahead with the update and delete functionality. You may give it a try and tell us about it in the comments. For the demo of the app and download of source code, you may follow following links. Happy Coding…!!!

Demo Download