Firebase-queue: стероїди для firebase

Про 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'е.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.