web-dev-qa-db-fra.com

Supprimer les données Firebase antérieures à 2 heures

Je voudrais supprimer toutes les données plus anciennes que deux heures. Actuellement, côté client, je parcours toutes les données et exécute une suppression sur les plus anciennes. Lorsque je fais cela, la fonction db.on ('value') est invoquée chaque fois que quelque chose est supprimé. De plus, les objets ne seront supprimés que lorsqu'un client se connecte et que pourrait-il se passer si deux clients se connectent en même temps? 

Où puis-je configurer quelque chose qui supprime les anciennes données? J'ai un horodatage à l'intérieur de chaque objet créé par un JavaScript Date.now (). 

22
carterw485

Firebase ne prend pas en charge les requêtes avec un paramètre dynamique, tel que "il y a deux heures". Toutefois, il peut exécute une requête pour une valeur spécifique, telle que "après le 14 août 2015 à 07:27:32".

Cela signifie que vous pouvez exécuter périodiquement un extrait de code pour nettoyer les éléments de plus de 2 heures à ce moment-là:

var ref = firebase.database().ref('/path/to/items/');
var now = Date.now();
var cutoff = now - 2 * 60 * 60 * 1000;
var old = ref.orderByChild('timestamp').endAt(cutoff).limitToLast(1);
var listener = old.on('child_added', function(snapshot) {
    snapshot.ref.remove();
});

Comme vous le remarquerez, j'utilise child_added au lieu de value et I limitToLast(1). Au fur et à mesure que je supprime chaque enfant, Firebase déclenche un child_added pour le nouvel "dernier" élément jusqu'à ce qu'il n'y ait plus d'éléments après le point limite.

Update: si vous souhaitez exécuter ce code dans Cloud Functions for Firebase:

exports.deleteOldItems = functions.database.ref('/path/to/items/{pushId}')
.onWrite((change, context) => {
  var ref = change.after.ref.parent; // reference to the items
  var now = Date.now();
  var cutoff = now - 2 * 60 * 60 * 1000;
  var oldItemsQuery = ref.orderByChild('timestamp').endAt(cutoff);
  return oldItemsQuery.once('value', function(snapshot) {
    // create a map with all children that need to be removed
    var updates = {};
    snapshot.forEach(function(child) {
      updates[child.key] = null
    });
    // execute all updates in one go and return the result to end the function
    return ref.update(updates);
  });
});

Cette fonction se déclenche chaque fois que des données sont écrites sous /path/to/items. Par conséquent, les nœuds enfants ne seront supprimés que lors de la modification des données.

Ce code est maintenant également disponible dans le répertoire functions-samples .

36
Frank van Puffelen

Dans la dernière version de l'API Firebase, ref () est remplacé par ref

var ref = new Firebase('https://yours.firebaseio.com/path/to/items/');
var now = Date.now();
var cutoff = now - 2 * 60 * 60 * 1000;
var old = ref.orderByChild('timestamp').endAt(cutoff).limitToLast(1);
var listener = old.on('child_added', function(snapshot) {
    snapshot.ref.remove();
});
6
Won Jun Bae

Vous pourriez regarder dans Planification de fonctions Firebase avec des tâches cron . Ce lien vous montre comment planifier une fonction Cloud de Firebase pour qu'elle s'exécute à un taux fixe. Dans la fonction Firebase planifiée, vous pouvez utiliser les autres réponses de ce fil de discussion pour rechercher les anciennes données et les supprimer.

3
James Oliver

J'ai une fonction de cloud déclenchée par http qui supprime les nœuds, en fonction de leur date de création et de leur date d'expiration.

Lorsque j'ajoute un nœud à la base de données, deux champs sont nécessaires: timestamp pour savoir quand il a été créé et duration pour savoir quand l'offre doit expirer.

 enter image description here

Ensuite, j'ai cette fonction cloud déclenchée par http:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

/**
 * @function HTTP trigger that, when triggered by a request, checks every message of the database to delete the expired ones.
 * @type {HttpsFunction}
 */
exports.removeOldMessages = functions.https.onRequest((req, res) => {
    const timeNow = Date.now();
    const messagesRef = admin.database().ref('/messages');
    messagesRef.once('value', (snapshot) => {
        snapshot.forEach((child) => {
            if ((Number(child.val()['timestamp']) + Number(child.val()['duration'])) <= timeNow) {
                child.ref.set(null);
            }
        });
    });
    return res.status(200).end();
});

Vous pouvez créer un travail cron qui demande toutes les X minutes à l'URL de cette fonction: https://cron-job.org/en/

Mais je préfère exécuter mon propre script, qui fait une demande toutes les 10 secondes:

watch -n10 curl -X GET https://(your-zone)-(your-project-id).cloudfunctions.net/removeOldMessages
1
Sergio