[TUT] Using Firebase with a Node JS Amazon Lambda

This tutorial will show you how you can use Firebase in an Amazon lambda, two methods will be outlined used the Firebase javascript SDK and using the Firebase REST API.

This post is going to cover the use of the realtime database. You might want to use the RTD in a lambda so that all clients share one database instance and if any other lambda’s (or other platforms) are running, your lambda will always receive the latest data.

What we’re going to do:

  • Configure Firebase so we have a realtime database instance ready
  • Discuss the two options of the Javascript SDK and REST API
  • Ensure our machine is setup to easily get javascript dependencies
  • Show example of Firebase javascript usage
  • Show example of Firebase REST API usage

One thing to note I assume you already have an Amazon lambda setup and ready to write some javascript into. I’ll show how to upload the code we write here but you need to have the lambda already created to upload it to. I’ll also use the web GUI but you can also do the same thing from the Amazon CLI.

Ok, here… we.. go.

Configuring Firebase turns out to be quite easy, open your project or create a new one, click the Database tab and you are done. Take a note of the url on this page you will needed it later. For the purpose of this blogpost the URL is. https://blogproject-f9a57.firebaseio.com/

firebase rtd

Notice on the picture its saying we have default security access rules. Security is not the aim of this blog post, but note what I am going to do next should not be how you have your security rules when you go to production. Click the rules tab and allow all access:

{
  "rules": {
    ".read": "auth != null || auth == null",
    ".write": "auth != null || auth == null"
  }
}

Great now we can read and write our database without auth (just for simplicity) now lets move to the Lambda side of things.

Firebase has two API’s that are of interest to us here.
The Javascript SDK : https://firebase.google.com/docs/database/web/start
The REST API : https://firebase.google.com/docs/database/rest/start

Using the javascript SDK will add dependencies and coupling to your implementation, but with the benefit of domain methods to call. The REST API is potentially more flexible has less coupling to an SDK but means you have to deal with raw http calls all the time. The choice is yours. I will show an example of using both.

Firebase Javascript SDK & Amazon Lambda

To use the SDK it is easiest to have npm installed. (You probably already have.) For those that don’t quickly run

brew install npm

from a terminal more info click here.

Creating a nodejs lambda looks like this:

my_lambda.js

exports.handler = (event, context, callback) => {
  context.succeed("done");
}

To use the javascript sdk you have to require it as a dependency of your lambda file but you also have to upload this dependency along with your lambda file. First thing to do is put your lambda file into a folder called whatever you want, we’ll call it /my_lambda/.

file in folder

Now add the Javascript SDK to the lambda file:

my_lambda.js


var Firebase = require('firebase'); 

exports.handler = (event, context, callback) => {
  context.succeed("done");
}

Then add the dependency to the folder. Using a terminal, navigate to the /my_lambda/ folder and type:

npm install firebase --prefix=./

This should then add the files to your folder:

screen-shot-2016-11-24-at-23-11-10

Now zip the contents of this folder /my_lambda/ (not the folder itself, just all the files underneath) and you can upload this to Amazon Lambda. You can do that from the dropdown next to the text “code entry type”.

upload zip

A great feature with Amazon Lambda here is that you can now continue copying the javascript online and not have to upload the dependencies zip file again until you change them.

Now you can read or write to the Firebase realtime database and use all the methods in the docs linked here.

Firebase.database().ref().child("hello") // creates a key called hello
    .set("world")                            // sets the key value to world
    .then(function (data) {
      // When the write is actually complete
    })
    .catch(function (error) {
      // if the write fails
    });

As an example of using the Firebase realtime database you could do something simple like this:

var Firebase = require('firebase');

exports.handler = (event, context, callback) => {
  
   // You can get these details from the 'overview' page of firebase
   // then click "add firebase to your web app"
   var config = { 
        apiKey: "foo-bar-foo",
        authDomain: "blogproject-1234.firebaseapp.com",
        databaseURL: "https://blogproject-1234.firebaseio.com",
        storageBucket: "blogproject-1234.appspot.com",
        messagingSenderId: "123456789"
    };

    Firebase.initializeApp(config);
        
    Firebase.database().ref().child("hello") // creates a key called hello
    .set("world")                            // sets the key value to world
    .then(function (data) {
      console.log('Firebase data: ', data);        
      context.succeed();                  // important that you don't call succeed until you are called back otherwise nothing will be saved to the database!
    })
    .catch(function (error) {
        console.log('Firebase error: ', error);
        context.fail();
    });
}

Firebase REST API & Amazon Lambda

The REST API does not require you to zip or upload any dependencies, it’s much simpler but you may notice it takes a lot more code. I’d just like to say I didn’t come up with the code myself and cgenco on Stackoverflow who posted the answer here.

Here is the code for reading and writing to the Realtime Database:

var https = require('https');
var firebaseHost = "blogproject-1234.firebaseio.com";
function fbGet(key){
  return new Promise((resolve, reject) => {
    var options = {
      hostname: firebaseHost,
      port: 443,
      path: key + ".json",
      method: 'GET'
    };
    var req = https.request(options, function (res) {
      res.setEncoding('utf8');
      var body = '';
      res.on('data', function(chunk) {
        body += chunk;
      });
      res.on('end', function() {
        resolve(JSON.parse(body))
      });
    });
    req.end();
    req.on('error', reject);
  });
}

function fbPut(key, value){
  return new Promise((resolve, reject) => {
    var options = {
      hostname: firebaseHost,
      port: 443,
      path: key + ".json",
      method: 'PUT'
    };

    var req = https.request(options, function (res) {
      res.setEncoding('utf8');
      var body = '';
      res.on('data', function(chunk) {
        body += chunk;
      });
      res.on('end', function() {
        resolve(body)
      });
    });
    req.end(JSON.stringify(value));
    req.on('error', reject);
  });
}

Now the great thing is once you have this code it’s really simple to do database reads or writes. You would put all the code shown above below your lambda, making your lambda simple:

exports.handler = (event, context, callback) => {
  fbPut("/hello", "world").then(res => {
    console.log("wrote to database");
    context.succeed();  // important that you don't call succeed until you are called back 
  })
}

Thats it! It’s actually quite simple (when you know how) to use Firebase within an Amazon Lambda. As always any questions just ask.