Promises as before filters

The Firebase JS library is callback-based, which feels pretty cumbersome after I got used to promises. So, the other day I wanted to have a FirebaseClient object that given a Firebase URL and credentials would give me a simple way to read and write data to it, something like this:

var data = new FirebaseClient(url, secret);


data.set('/some/path', value)

In Firebase you can have “public” databases that can be accessed anonymously, and “private” databases that you can still connect to anonymously, but can’t access any data before you authenticate: connection and authentication are two separate and disconnected in time steps. You can technically connect and try to access the data, but for a private database you’ll get a permission error.

So in my FirebaseClient’s get and set I would have to first ensure the authentication finished and only then try to access the data, both of which are async callback-based calls.

In synchronous worlds like Rails, you achieve this with synchronous before_filters, but this is not how it works in callback-based JS.

It turns out that it’s pretty easy to get code that is comparably clear with the synchronous before_filters if I wrap the authentication in a promise:

function FirebaseClient(url, secret) {
  var ref = new Firebase(url);
  this.authenticate = authenticate(ref, secret);

function authenticate(ref, secret) {
  // return a promise to authenticate

then make it a prerequisite in methods that need authentication finished before doing their own work:

FirebaseClient.prototype.get = function(path) {
  return this.authenticate.then(get(path));

function get(path) {
  // return a function which does the actual data access

Before being resolved, the authenticate promise will queue everything that is then()ed on it. After it’s resolved, it will just just pass through to the subsequent then() calls. Nice! :)