web-dev-qa-db-ja.com

2時間以上前のFirebaseデータを削除する

2時間以上前のデータを削除したいと思います。現在、クライアント側では、すべてのデータをループし、古いデータに対して削除を実行します。これを行うと、何かが削除されるたびにdb.on( 'value')関数が呼び出されます。また、クライアントが接続したときにのみ物事が削除されます。2つのクライアントが同時に接続した場合はどうなりますか?

古いデータを削除する何かをどこで設定できますか? JavaScript Date.now()によって作成された各オブジェクト内にタイムスタンプがあります。

27
carterw485

Firebaseは、「2時間前」などの動的パラメーターを使用したクエリをサポートしていません。ただし、canは、「2015年8月14日7:27:32 AM以降」など、特定の値のクエリを実行します。

つまり、コードのスニペットを定期的に実行して、その時点で2時間より古いアイテムをクリーンアップできます

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

お気付きのとおり、valueの代わりに_child_added_を使用し、limitToLast(1)を使用します。各子を削除すると、Firebaseは、カットオフポイントの後にアイテムがなくなるまで、新しい「最後の」アイテムに対して_child_added_を起動します。

Update: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);
  });
});
_

この関数は、データが_/path/to/items_で書き込まれるたびにトリガーされるため、子ノードはデータが変更されている場合にのみ削除されます。

このコードは _functions-samples_ repo でも利用できるようになりました。

39

Firebase APIの最新バージョンでは、ref()が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

Cronジョブを使用したFirebase関数のスケジューリング を調べることができます。そのリンクは、Firebase Cloud Functionを固定レートで実行するようにスケジュールする方法を示しています。スケジュールされたFirebase Functionでは、このスレッドの他の回答を使用して古いデータを照会し、削除できます。

3
James Oliver

ノードが作成された日時と有効期限に応じて、ノードを削除するhttpトリガークラウド機能があります。

データベースにノードを追加するとき、2つのフィールドが必要です:timestampそれがいつ作成されたかを知るため、および durationは、オファーの有効期限がいつ切れるかを確認します。

enter image description here

次に、この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();
});

X分ごとにその関数のURLにリクエストを送信するcronジョブを作成できます。 https://cron-job.org/en/

しかし、10秒ごとに要求を行う独自のスクリプトを実行することを好みます。

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