webentwicklung-frage-antwort-db.com.de

Löschen Sie die Firebase-Daten, die älter als 2 Stunden sind

Ich möchte alle Daten löschen, die älter als zwei Stunden sind. Auf Client-Seite durchlaufe ich derzeit alle Daten und lösche alle älteren Daten. Wenn ich dies tue, wird die Funktion db.on ('value') jedes Mal aufgerufen, wenn etwas gelöscht wird. Außerdem werden Dinge nur gelöscht, wenn ein Client eine Verbindung herstellt. Was kann passieren, wenn zwei Clients gleichzeitig eine Verbindung herstellen? 

Wo kann ich etwas einrichten, das alte Daten löscht? Ich habe einen Zeitstempel in jedem Objekt, das von einem JavaScript-Date.now () erstellt wurde. 

22
carterw485

Firebase unterstützt keine Abfragen mit einem dynamischen Parameter, z. B. "vor zwei Stunden". Es kann jedoch eine Abfrage für einen bestimmten Wert ausführen, z. B. "nach dem 14. August 2015, 7:27:32 Uhr".

Das bedeutet, dass Sie regelmäßig einen Codeausschnitt ausführen können, um Elemente zu bereinigen, die zu diesem Zeitpunkt älter als 2 Stunden sind :

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();
});

Wie Sie feststellen werden, verwende ich child_added Anstelle von value und I limitToLast(1). Wenn ich jedes untergeordnete Element lösche, gibt Firebase für das neue "letzte" Element einen child_added Aus, bis nach dem Grenzwert keine Elemente mehr vorhanden sind.

Update : Wenn Sie diesen Code in Cloud Functions for Firebase ausführen möchten:

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);
  });
});

Diese Funktion wird ausgelöst, wenn Daten unter /path/to/items Geschrieben werden, sodass untergeordnete Knoten nur gelöscht werden, wenn Daten geändert werden.

Dieser Code ist jetzt auch im functions-samples - Repo verfügbar.

39

In der neuesten Version der Firebase-API wird ref () in ref geändert

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

Sie können in Einplanung von Firebase-Funktionen mit Cron-Jobs nachschlagen. Dieser Link zeigt Ihnen, wie Sie eine Firebase Cloud-Funktion so planen, dass sie zu einer festen Rate ausgeführt wird. In der geplanten Firebase-Funktion können Sie die anderen Antworten in diesem Thread verwenden, um alte Daten abzufragen und sie zu entfernen.

3
James Oliver

Ich habe eine http-getriggerte Cloud-Funktion, die Knoten löscht, je nachdem, wann sie erstellt wurden, und deren Ablaufdatum.

Wenn ich einen Knoten zur Datenbank hinzufüge, sind zwei Felder erforderlich: timestamp, um zu wissen, wann er erstellt wurde, und duration, um zu wissen, wann das Angebot ablaufen muss.

 enter image description here

Dann habe ich diese http-Cloud-Funktion ausgelöst:

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();
});

Sie können einen Cron-Job erstellen, der alle X Minuten eine Anfrage an die URL dieser Funktion sendet: https://cron-job.org/de/

Ich ziehe es jedoch vor, mein eigenes Skript auszuführen, das alle 10 Sekunden eine Anforderung stellt:

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