No-Backend Development with Firebase


Today's DB Objectives:


NoBackend: Databasing without a server

I want you to be familiar with a wide range of options for data management. If you have a small single-player game, but still compare scores with friends, you might not want to involve mongo or some SQL server. For front-end minded developers there are new tools emerging which take away the pain of hosting your own database. This allows static files to be served (via a CDN for instance) that then run all sorts of dynamic querying from the client's computer. Depending on timing I'll show you how to set up local storage on Thursday. Today we'll play with Firebase.

Hello Firebase

Firebase is a restful, event-driven, database operating out of the cloud. Every piece of data has a unique URL and at that URL you can do CRUD using requests (or let someone wrap that functionality for you). The goal is to have cloud-backed persistence with dynamic alerts to changes in the data without having to do much more than write basic javascript. If you want to skip ahead we will be following this guide, roughly.

Hello World in Javascript

To play with this we want to understand a little bit about client-side coding. Fire up JsFiddle a fast way to play with front-end basics.

This will be enough for us to get results from the results of a function running. There is a good bit going on here including HTML5 tags, CSS Selectors, and dynamically altering a page.

Mini-Task 1: Use the tag list and CSS selector (tip here) to make a list of thing with every other thing colored salmon.

Mini-Task 2: Use javascript's function document.querySelectorAll to log an array having each thing in it.

Setting up Firebase

  1. Go to Firebase, make an account and create an app. That will create a database for you with a url like https://hello437.firebaseio.com.
  2. In your jsFiddle add the firebase library in the left hand column under external resources. At the time of this writing I would use: https://cdn.firebase.com/js/client/2.2.7/firebase.js.
  3. Add a couple of lines like this:
    
    var rootRef = new Firebase('https://YOUR-APP-NAME-HERE.firebaseio.com/');
    rootRef.set({hello: "world"});
    
    
  4. Visit https://YOUR-APP-NAME-HERE.firebaseio.com/

So basically your database is just JSON. But you can use the keys as URLS, so https://YOUR-APP-NAME-HERE.firebaseio.com/hello is the location of that data "world".

Mini-Task A: Alter the above set to be a more complex JSON object with several keys and some nesting of JSON. Inspect the difference online.

In your code you can traverse the tree with .child("path/here"). For instance try: rootRef.child("/bananas").set({status:"Delicious"}). Likewise .parent() will move up the tree.

Mini-Task B: move down your tree to a leaf and add another round of interesting JSON. Inspect the results.

Event-Based Reading

In Firebase you set your handler to the level you care about and register an event listener for changes. The most basic event is value which gets fired once when you ask the first time and then again everytime the data changes. Let's play with that.

Try this snippet of code (assuming you have the same paragraph element from before and a "hello" attribute in your database):


var hello = "loading...";
rootRef.child("hello").on("value", function(snapshot){
    hello = snapshot.val();
    document.querySelector(".para").innerHTML = "Hello: " + hello;
});

When you run your fiddle with this code you'll see the value of hello on screen. Now, in a different tab, go directly to your database and change the value of hello. It should change in your jsFiddle.

Add the following HTML:


<input type="text" id="chat"></input>
<button type="button" id="send">Click me</button>

And the following javascript:


var elbutton = document.querySelector('#send');
elbutton.addEventListener('click', function(){
    var messagebox = document.querySelector('#chat');
    rootRef.set({hello: hello + " :: " + messagebox.value});
    messagebox.value = "";
}, false);

We want to take some input from the user and submit it to the database. We will wait for the user to click the button then send that message to firebase.

Mini-Task Z: Collaborate with a neighbor and chat with each other online. You've just built a very simple chat engine.

You can use .off() to stop listening and .once() to listen only once.

Mini-Task ZZ: Use once instead of on and observe the difference.

Updating

Updating works very much like $set in mongo. It will honor the key value pairs you send without destroying any of the other attributes. (.set will erase everything that you point at.)

Mini-Task U: At your database set the value of user to {name: "Jimmy", occupation: "Rock God"}

Mini-Task U2: Now update the user.name to "Jimmy Page without changing occupation.

Mini-Task U3: Replace the user with {name: "YOUR-NAME-HERE", hobbies: "coding and cookies"} make sure occupation is gone.

Deleting

Just use .remove.

Mini-Task R: Create something and remove it.

Arrays in Firebase

Firebase does allow arrays, but has some interesting rules. If you save the array ["a", "b", "c"] the corresponding JSON object will look like {0: "a", 1:"b", 2:"c"}. But using those indexes directly can lead to some concurrency issues, namely two people writing to the same index at the same time. So they provide a .push() method which will treat a given attribute like an array but generate UUIDs for the indices.

Mini-Task Arr: set a standard array and look at the result.

Mini-Task Arr-Matey: now try several pushes and look at the result.

Mini-Task research-array: Look in the documentation to find a way of retreiving that UUID key.

The other events

Other events that they allow are child_added, child_changed, child_removed, child_moved in this case you can get the latest thing in an array.

Major-Task: refactor our "chat app" into an array based structure where each message has form {author: "name here", message: "text here"} and child_added is what triggers the next message.