Firebase-queue: steroids for firebase

About Firebase more than once wrote on a geek magazine The key advantage of this system is that in some cases it is possible to build a complete web application working with data in real time on it. Having the ability to edit the rules of access to the database and the fact that these rules can be arranged on the basis of users (who were also brought here), in principle, you can do without any backend. But usually there are problems that are better solved "from the outside" than to produce bicycles in the rules ( for example ).

In mid-May, developers announced the release of firebase-queue . This is a javascript-library with which you can organize work with data in the database, as with tasks. It works as follows: we define a task cell usingQueue () on the server to establish a connection. Now, when a new element appears in this cell, the server will take the necessary actions, if necessary, notify about progress and errors, and upon completion, delete the task. As a result, we get the opportunity to cover many problems arising in development with Firebase - to reconcile data, conduct their additional validation (for example, check for spam and mate), send them to another place (for example, upload a picture to the hosting) and more.

As an example, take the above question from stackoverflow. We have an object with the nth number of elements. After adding / removing an item, we want to update the total count. In the database, we define two objects: elements and length . Also in the rules specify the addnode task cellsand rmnode . In them, we will send from the client the object that we want to receive and delete accordingly from elements .

var ref = new Firebase('https://***.firebaseio.com');
var addNode = function(text) {
  // используем kriskowal/q для промисов
  var deferred = Q.defer();
  var task = ref.child('addnode').push({ new: text }, function(e) { if (e) {
    deferred.reject(e);
  } else {
    /* Следим за изменениями в нашей задаче. Вызов progress() с сервера
       изменит значение _progress, resolve() - удалит задачу.
    */     
    ref.child('addnode/'+task.key()).on('value', function(d) {
      var v = d.val();
      if(v == null) {
        deferred.resolve();
      } else {
        deferred.notify(v._progress);
      }
    })
  }});
  return deferred.promise;
}
var rmNode = function(k) {
  var deferred = Q.defer();
  var task = ref.child('rmnode').push({ key: k }, function(e) { if (e) {
    deferred.reject(e);
  } else {
    ref.child('addnode/'+task.key()).on('value', function(d) {
      var v = d.val();
      if(v == null) {
        deferred.resolve();
      } else {
        deferred.notify(v._progress);
      }
    })
  }});
  return deferred.promise;
}

We attach Firebase-queue to task cells. As soon as a new task appears, we already perform the necessary manipulations on the server:
var ref = new Firebase('https://***.firebaseio.com');
var length;
ref.child('length').once('value', function(d) {
  length = d.val();
});
var addNodeQueue = new Queue(ref.child('addnode'), {}, function(data, progress, resolve, reject) {
  ref.child('elements').push(data.new, function(e) { if (e) {
    reject(e);
  } else {
    progress(50);
    length++;
    ref.child('length').set(length, function(e) { if (e) {
      reject(e.message);
    } else {
      resolve();
    }});
  }});
});
var rmNodeQueue = new Queue(ref.child('rmnode'), {}, function(data, progress, resolve, reject) {
  ref.child('elements/'+data.key).remove(function(e) { if (e) {
    reject(e);
  } else {
    progress(50);
    length--;
    ref.child('length').set(length, function(e) { if (e) {
      reject(e);
    } else {
      resolve();
    }});
  }});
});

The rules will be as follows:

{
  "rules": { 
    "addnode": {
      "$taskId": { 
        "new": {
          ".validate": "newData.isString()"
        }
      }
    },
    "rmnode": {
      "$taskId": { 
        "key": {
          ".validate": "root.child('elements/'+newData.val()).exists()"
          // элемент с этим ключом должен находится в бд
        }
      }
    }
  }
}

In order not to overload and preserve the overview nature of the article, I decided to omit the story about the security rules for tasks, task specifications and options that can be specified for Queue () . All this is fine (as well as all their documentation) is described on the project page on github.

Also popular now: