File d'attente Firebase
Comment utiliser la file d’attente Firebase comme backend pour votre application
Firebase fournit le backend en tant que service, en tant que développeur d’applications, vous n’avez pas la possibilité d’avoir du code backend.
Cet exemple montre comment utiliser la file d’attente Firebase pour créer un backend qui fonctionnera au-dessus de la base de données Firebase et servira de backend pour votre application frontale.
Avant d’entrer dans le code, comprenons l’architecture, comment cela va fonctionner. Par souci de brièveté, supposons que nous utilisons le site Web comme serveur frontend et NodeJs comme backend
Conditions préalables
-
Créez une application Firebase à l’aide de votre compte Google
-
Ajoutez Firebase à votre page Web. Utilisez
bower install firebase --save
-
Créez un compte de service en utilisant votre nouveau compte firebase créé (Paramètres-> Autorisations -> Comptes de service -> CRÉER UN COMPTE DE SERVICE -> (spécifiez le nom et cochez cette case “Fournir une nouvelle clé privée”) -> enregistrez le fichier json, nous en aura besoin plus tard.
-
Configurez le serveur NodeJs qui peut être hébergé dans votre environnement préféré
-
Créez le point de terminaison suivant dans
queue/specs
“request_response”:
{ "error_state": "request_error_processing", "finished_state": "finished_state", "in_progress_state": "request_in_progress", "start_state": "request_started" }
-
À l’intérieur du serveur NodeJs, installez la version côté serveur de Firebase, “npm install firebase –save”, et initialisez votre compte de service à l’aide du fichier json que nous avons obtenu à l’étape 3, il ressemble à ceci
firebase.initializeApp({ serviceAccount: ‘./your_file.json’, databaseURL: ‘get_from_firebase_account’ });
Architecture
Voici tout le cycle comment cela fonctionne.
Du côté frontal, vous allez suivre ces étapes
- En utilisant Firebase Web SDK, vous écrivez vos demandes directement dans la base de données Firebase dans la file d’attente/tâches du point de terminaison, appelons cela votre demande que vous envoyez au backend.
- après avoir inséré votre tâche, vous enregistrez l’écouteur sur le point de terminaison
queue/tasks/{taskKey}
qui sera appelé lorsque le backend aura fini de traiter votre demande, en écrivant la réponse dans la tâche ci-dessus
Dans le backend, vous allez faire ces étapes
- Créer un serveur qui écoute à l’infini les “files d’attente/tâches” du point de terminaison
- Traite vos tâches et réécrit les données de réponse dans
file d'attente/tâches/réponse
- Supprimer la tâche
Tout d’abord, créez cette fonction d’assistance, qui fournit un moyen de gérer les rappels et les promesses ensemble
function createPromiseCallback() {
var cb;
var promise = new Promise(function (resolve, reject) {
cb = function (err, data) {
if (err) return reject(err);
return resolve(data);
};
});
cb.promise = promise;
return cb;
}
Dans le côté frontal, vous aurez cette fonction
function sendRequest(kind, params, cb) {
cb = cb || createPromiseCallback();
var requestObject = {
kind: kind,
params: params
};
var tasksRef = firebase.database().ref('queue/tasks');
var requestKey = tasksRef.push().key;
var requestRef = tasksRef.child(requestKey);
function requestHandshake(snap) {
if (snap && snap.exists() && (snap.val().response || snap.val()._state === config.firebase.task.finishState || snap.val()._error_details)) {
var snapVal = snap.val();
if (snapVal._error_details) {
cb(snapVal._error_details.error);
} else {
cb(null, snapVal.response);
}
requestRef.off('value', requestHandshake);
}
}
var bulkUpdate = {};
bulkUpdate['queue/tasks/' + requestKey + '/request'] = requestObject;
bulkUpdate['queue/tasks/' + requestKey + '/_state'] = config.firebase.task.startState;
firebase.database().ref().update(bulkUpdate)
.then(function (snap) {
requestRef.on('value', requestHandshake);
}).catch(function (err) {
cb(err);
});
return cb.promise;
}
vous pouvez utiliser cette fonction comme sendRequest('CreateHouseFacade', {houseName:'Test'})
.
Le paramètre Kind est pour le backend, pour savoir quelle méthode appeler pour traiter la demande. Params sert à transmettre des informations supplémentaires sur les paramètres.
Et voici le code backend
const database = firebase.database();
const queueRef = database.ref('queue');
const queueOptions = {
'specId': 'request_response',
'sanitize': false,
'suppressStack': false,
'numWorkers': 3
};
function removeTask(task) {
var taskRef = queueRef.child(`tasks/${task._id}`);
return taskRef.remove();
}
function processTask(data, progress, resolve, reject) {
try {
requestHandler(data.request).then(response => {
data.response = response || null;
return resolve(data);
}).catch(err => {
return reject(err);
}).then(snap => {
removeTask(data);
});
} catch (err) {
reject(err).then(snap => removeTask(data));
}
}
function requestHandler(request) {
if (!request || !request.kind) throw new Error('Absent Request or Kind');
var deferredResponse = requestHandlerFactory(request.kind, request.params);
return deferredResponse;
}
function requestHandlerFactory(kind, params) {
// It includes mapping all your backend services
switch (kind) {
case 'CreateHouseFacade': return myService(params)
default: throw new Error(`Invalid kind ${kind} was specified`);
}
}
La fonction myService
contient votre code de logique métier qui va accomplir la requête CreateHouseFacade
.