Про Firebase уже не раз писали на хабре. Ключевым преимуществом этой системы является то, что в некоторых случаях на ней можно построить завершенное веб-приложение работающее с данными в реальном времени. Располагая возможностью редактирования правил доступа к базе данных и тем что эти правила можно устроить на основе пользователей (которых сюда тоже завезли), в принципе можно обойтись и без какого-либо backend’a. Но обычно возникают такие проблемы, которые лучше решить «со стороны» чем плодить велосипеды в правилах (например).
В середине мая разработчики объявили о выходе firebase-queue. Это javascript-библиотека с помощью которой можно организовать работу с данными в базе, как с задачами. Работает это следующим образом: определяем ячейку задач, используя Queue() на сервере устанавливаем связь. Теперь, когда в этой ячейке появится новый элемент, сервер сделает необходимые действия, если нужно оповестит о прогрессе и ошибках, и по завершению удалит задачу. В итоге мы получаем возможность покрыть много проблем возникающих в разработке с Firebase — согласовать данные, провести их дополнительную валидацию (например проверить на спам и мат) отправить их в другое место (например загрузить картинку на хостинг) и другое.
В качестве примера возьмем вышеупомянутый вопрос из stackoverflow. Имеем объект с n-ым количеством элементов. Хотим после добавления/удаления элемента обновлять счетчик общего количества. В базе определим два объекта: elements и length. Также в правилах укажем ячейки задач addnode и rmnode. В них с клиента будем отправлять тот объект, который хотим получить и удалить соответственно из 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; }
Firebase-queue прицепляем на ячейки задач. Как только появляется новая задача, уже на сервере производим необходимые манипуляции:
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(); }}); }}); });
Правила будут следующие:
{ "rules": { "addnode": { "$taskId": { "new": { ".validate": "newData.isString()" } } }, "rmnode": { "$taskId": { "key": { ".validate": "root.child('elements/'+newData.val()).exists()" // элемент с этим ключом должен находится в бд } } } } }
Дабы не перегружать и сохранить обзорный характер статьи, решил опустить рассказ о правилах безопасности для задач, спецификациях задач и опциях, которые можно указать для Queue(). Это все прекрасно (как и вся их документация) описано на странице проекта на github’е.
ссылка на оригинал статьи http://habrahabr.ru/post/266355/
Добавить комментарий