Firebase is a cloud hosted data service that we will use to store data for our web applications. Rather than write our own server-side scripts, we can leverage the firebase platform to manage our data. As a real time database, Firebase will enable us to create interactive applications where users create, read, and share data (such as chat-rooms or multiplayer games).
Contents
- Firebase Homepage
- Getting Started
- Firebase Data Structure
- Reading and Writing to a Database
- Create a Firebase Storage Reference
There are a few steps you'll need to take in order to get started using Firebase (more info here).
First, you'll need to Get Started by signing up for an account. Because Firebase is owned by Google, you'll be prompted to sign-in with (or create) a google account when you click here:
Once you've signed into your account, you'll want to navigate to your console where you can create a project:
From your console, you can click the Create New Project button, which will prompt you to create a project, which you should give a short and descriptive name:
Once you've created a project, you can click on your project card to be navigated to your project interface at https://console.firebase.google.com/project/PROJECT-URL/overview. You can then navigate using the tab on the left to interact with specific parts of your project, such as the database:
Once you've set up a project your account, you'll need to link your web page to the Firebase project. This can be done in a few simple steps:
First, you'll need to load the Firebase library in the <head>
section of your HTML file:
<script src="https://www.gstatic.com/firebasejs/3.4.0/firebase.js"></script>
Then, in your JavaScript file, you should initialize your project:
// Configuration: replace <THESE_VALUES> with your values from firebase
var config = {
apiKey: "<API_KEY>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
storageBucket: "<BUCKET>.appspot.com",
};
// Initialize Firebase, providing you read/write access to the database
firebase.initializeApp(config);
To get the values for the config
variable above, navigate to the settings of your project from the Firebase menu:
From this location, you should click on Add Firebase to your web app to access the config
options for your project:
In order to read and write data to your database, you'll either need to authenticate your users (more on this in the next learning module), or change your database rules. To enable read/write access by anyone (not necessarily suggested from a security standpoint), you'll need to navigate to the database/rules tab and enter the following code:
{
"rules": {
".read": true,
".write": true
}
}
When you do this and click Publish, your should see the following screen:
You will now (finally) have access to your firebase database from your web application.
In order to properly use Firebase as a data storage service, it's crucial to understand how that data is structured. All of the data for a project is stored in the same JSON (JavaScript Object Notation) object. In other words, all of the data is stored in a single object (just as you would store information in an object in JavaScript). For example, if you had a simple to do list applicaiton, the data could be stored as follows:
// All data is stored in the same object
{
"todos":{
"one":{
"description": "Do INFO 343 Homework",
"status":"Incomplete",
"urgency":"Low"
},
"two":{
"description": "Do INFO 474 Homework",
"status":"Incomplete",
"urgency":"High"
}
}
}
Data from your tree is accessed just like referencing information from an Object: using it's key. Object keys can be specified from your JavaScript file, or will be assigned automatically in Firebase. While we won't encounter any huge data in this class, it's important to understand best practices for storing data, such as limiting the amount of nesting you do in your JSON Tree.
Now that we know how to set up a project on Firebase, connect to it in our JavaScript file, and have an understanding of the data structure, we can begin interacting with our data (JSON object). Because you'll often start off with an empty project, we'll begin by discussing how to create data on Firebase.
In order to perform any data action to our database, we'll first have to create a reference to that data. A reference can point to the entire data structure, or a specific point in the JSON tree. For example, to point to the entire data structure, you can use the firebase.ref
method:
// Initialize Firebase, providing you read/write access to the database
firebase.initializeApp(config);
// Create a reference to the root of database
firebase.database().ref();
Firebase is intelligent enough to create new child elements on the tree when you reference them for the first time:
// Create a reference to a new child called "todos"
var todos = firebase.database().ref('todos');
Once you have created a reference, you'll be able to store data in your database. The method for creating your elements will depend on your data structure, but let's imagine that our todos
reference is supposed to have multiple child elements, each with key/value pairs explaining an item on a to-do list. To add a new item, you can specify the push
method:
// Create a reference to a new child called "todos"
var todos = firebase.database().ref('todos');
// Write a new item
// Push something into todos
todos.push({
description: 'Write learning modules',
urgency: 'High',
priority: 'incomplete'
});
As soon as you execute that code, an child element will be added to the todos
reference (which is a child of the root element):
When you create a reference to a Firebase data store, you can listen to changes to that part of your data structure. There are a variety of methods for listening to event changes, the first of which we'll introduce is value
.
Setting an event listener on value
will return the data when the connection is made, as well as any time that there is a change to the reference (include all children):
// Create a reference to a new child called "todos"
var todos = firebase.database().ref('todos');
// Listen to changes to 'todos': will execute on connection, and on any change
todos.on('value', function(snapshot) {
// Get the value of the data
var data = snapshot.val();
// Do whatever you want with the Object...
});
In the above code, snapshot
contains a snapshot of the data structure at the time of the event. To retrieve the values from the snapshot, the snapshot.val()
method is invoked. This will return the data object with child elements of key/value pairs.
If there is data that you only need to read once, you can invoke the once
method, which will not listen to changes to the reference.
todos.once('value').then(function(snapshot){
// Get the value of the data
var data = snapshot.val();
// Do whatever you want with the Object...
})
Using the keys of particular objects, you can easily modify the contents of your Firebase database. First, let's consider how we can get the keys of each element in our data store:
// Listen to changes to 'todos': will execute on connection, and on any change
todos.on('value', function(snapshot) {
// Get the value of the data
var data = snapshot.val();
// Iterate through key/value pairs
Object.keys(data).forEach(function(key) {
// Get value of object using key
var value = data[key];
// Create an element with the key as an ID
var body = $('body');
var button = $('<button>').attr('id', key);
button.on('click', function() {
// Get the key back from the button
var key = this.id;
// Update element
});
body.append(button);
});
});
In the above example, we're keeping track of the key by storing it in the id
of the <button>
that we create. Then, in the onClick
function, we're able to reference the id
to reference the key of our data store.
To update our element, we will create a reference to it using the child
method of the todos
reference, and set
the values:
// Set the child value
todos.child(id).set({
description: 'new description',
priority: 'new priority',
status: 'new status'
});
Elements can be deleted using the remove
method. Again, if you keep track of the key
of each object, referencing (and removing it) is simple:
todos.child(id).remove();