Firebase CRUD operations with JavaScript and jQuery
Learn how to do Read and Write Data operations on Firebase Realtime Database i.e. Firebase CRUD operations with JavaScript and jQuery.

In this tutorial we are going to learn how to do data operations on Firebase i.e. CRUD operations in Firebase with JavaScript and jQuery.
This tutorial is a follow up to the tutorial Auth Schemes in Google Firebase and Custom Router for Firebase jQuery App.
To understand Firebase CRUD operations, we will have the Movie as our entity which is being added, viewed, updated or removed.
Router
As our custom router is going to load the template, and fill it with data in following way:
var Auth = require('./auth');
var Router = require('./router');
//Redirect to some Page or URL
var redirect = function(to) {
appRouter.go(to)
}
var appRouter = new Router({
mountPoint: '#root',
indexRoute: 'index',
routes: {
login : {
path: 'login',
templateUrl: 'partials/login.html',
onEnter: function() {
var user = Auth.checkLoggedInUser();
if( !user && window.location.hash.match('/login') ){
return true;
} else {
return 'index';
}
},
controller: require('./controllers/login')(Auth, redirect)
}
}
});
Here in above code, you can see the controller key for a particular route. Which grabs the module and executes it with its dependencies i.e. Auth
and redirect
.
Add and Update
Add Data
So To Add the data, following method from Firebase API can be used:
var key = firebase.database().ref().child('movies').push(data).key;
In the above code we are getting the reference of DB from firebase.database().ref()
. And then going to the movies
node by .child(‘movies’)
where we are going to save the new data.
And then pushing it to the node by .push(data)
. This saves the data to Firebase and returns the newly created object reference.
So the .key
attribute after push
will give the key with which new data has been saved.
Now for out application, we want to save same data in two different locations/endpoints simultaneously. So we are going to follow the Update approach to add the new data.
In this first we push the empty data to generate a new empty node with key. And then do update operations on the key
itself.
Following code demonstrates that.
var Key = firebase.database().ref().child('movies').push().key;
// Write the new post's data simultaneously in the movies list and the user's movie list.
var updates = {};
updates['/movies/' + Key] = movie;
updates['/user-movies/' + uid + '/' + Key] = movie;
return firebase.database().ref().update(updates);
Here we have created an associative array with all the updates that we wanna perform. So for two paths, same data is going to be saved.
Update Data
This updates array can be passed to the update method on the Firebase DB reference as firebase.database().ref().update(updates)
.
In our example, it will be done in three steps
- Load the Data
- Fill The Data
- After edits, on clicking save, Save the data on same reference
First and Third step will utilize the key that they receive from the router. Following code demonstrates that:
//See complete file at
//https://github.com/time2hack/movie-db/blob/master/src/js/controllers/edit.js
var query = firebase.database().ref("movies/"+params.id);
//Fire Query
query.once("value").then(fillData)
//Fill The form data
function fillData(snap) {
var data = snap.val();
console.log(data)
$('#movieName').val(data.movieName);
$('#releaseYear').val(data.releaseYear);
$('#generes').val((data.generes || []).join(', '))
$('#duration').val(data.duration);
$('#directors').val((data.directors || []).join(', '))
$('#actors').val((data.actors || []).join(', '))
$('#imdbUrl').val(data.imdbUrl);
}
//Save function (similar to Adding the data.
//This time we don't generate new key but utilize the one received from Router parameter
function saveMovie(movie) {
var uid = firebase.auth().currentUser.uid;
var postKey = params.id; //Params is received from the Router
var updates = {};
updates['/movies/' + postKey] = movie;
updates['/user-movies/' + uid + '/' + postKey] = movie;
return database.ref().update(updates);
}
Read
To list and view the data, we just need to execute the query. And the Firebase DB reference is query by itself. So on creating the reference and then attaching the event handler will let us read and render the results.
Following code queries and passes to the render function for single item.
var query = firebase.database().ref("movies").limitToFirst(20);
query.once("value")
.then(function(snapshot) {
snapshot.forEach(renderSingleSnapshot);
}).then(function(){
$(document).find('#list').html(markup);
});
var renderSingleSnapshot = function(singleSnapshot){
// ... code to render
}
The data received from Firebase is called snapshot
. The snapshot
has few methods
and iterators
with it. Those can be used to retrieve values and keys from snapshot or loop over the data.
var firebase = require('firebase');
var $ = require('jquery');
var durationConvertor = require('../utils/duration');
var ListController = function() {
return function () {
var userId = firebase.auth().currentUser.uid;
// Get a reference to the database service
var markup = '';
var database = firebase.database();
var query = firebase.database().ref("movies").orderByChild('createdAt').limitToLast(20);
query.once("value")
.then(function(snapshot) {
snapshot.forEach(renderSingleSnapshot);
}).then(function(){
$(document).find('#list').html(markup);
});
var renderSingleSnapshot = function(movieRef) {
var movie = movieRef.val();
console.log(movieRef.key, movie);
var imdb = '';
var editLink = '';
var html = '';
if(movie.uid === userId) {
editLink = ` <a href="#/edit/${movieRef.key}+"><i class="fa fa-pencil" aria-hidden="true"></i></a>`;
}
viewLink = `<a href="#/view/${movieRef.key}">${movie.movieName}</a>`
if( movie.imdbUrl !== '' ){
imdb += ` <a href="${movie.imdbUrl}" target="_blank"><i class="fa fa-imdb" aria-hidden="true"></i></a>`;
}
html += `
<li class="list-group-item media movie">
<div class="media-body">
<h5 class="media-heading">${viewLink}${imdb}${editLink}</h5>
<h6><b>Director: </b>${movie.directors.join(', ')}</h6>
<small><b>Released in: </b>${(movie.releaseYear)}<br/>
<b>Duration: </b>${durationConvertor(movie.duration)}<br/>
<b>Actors: </b>
<small>${(movie.actors || movie.stars).join(', ')}</small>
</div>
<div class="media-right">
<img class="media-object" height="125" src="${movie.poster}" alt="${movie.movieName}" />
</div>
</li>`;
//Add new ones on top
markup = html + markup;
}
}
}
ListController.toggleStar = function(movieUniqueId){
console.log(movieUniqueId);
}
module.exports = ListController;
Remove
Removing the data is also not a hassle, though we are not implementing it in out MovieDB application for now.
Following code shows that remove()
method can be used to remove the and key reference:
firebase.database().ref("movies").child(key).remove();
So creating a function and calling it with event handler will look like that. Though the button to trigger the delete event must have the data-key
attribute. And the value of this attribute is the key which needs to be removed.
var remove = function(e){
e.preventDefault();
e.stopPropogation();
var key = $(this).data('key');
if(confirm('Are you sure?')){
firebase.database().ref("movies").child(key).remove();
}
}
$(document).on('click', '.btn-remove-key', remove);
Hence the above code will be functional for the buttons and links created like this:
<button type="button" class="btn-remove-key" data-key="-dsdsf-sample-key">Delete</button>
<a ref="#" class="btn-remove-key" data-key="-dsdsf-sample-key">Delete</a>
<span class="btn-remove-key" data-key="-dsdsf-sample-key">Delete</span>
So in this way, you can perform Firebase CRUD Operations. Please let us know about your views about the article in comments.
Conclusion
Let me know through comments ? or on Twitter at @heypankaj_ and/or @time2hack
If you find this article helpful, please share it with others ?
Subscribe to the blog to receive new posts right to your inbox.