删除超过2小时的firebase数据

时间:2015-08-14 07:28:51

标签: javascript angularjs firebase

我想删除两个小时以前的任何数据。目前,在客户端,我遍历所有数据,并对任何较旧的数据运行删除。当我这样做时,每次删除某些内容时都会调用db.on(' value')函数。此外,只有在客户端连接时才会删除内容,如果两个客户端同时连接会发生什么?

我可以在哪里设置删除旧数据的内容?我在JavaScript Date.now()创建的每个对象中都有一个时间戳。

5 个答案:

答案 0 :(得分:39)

Firebase不支持使用动态参数的查询,例如“两小时前”。然而,可以执行特定值的查询,例如“2015年8月14日之后,上午7:27:32”。

这意味着您可以定期运行一段代码来清理当时超过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();
});

您会注意到我使用的是child_added而不是value,而我limitToLast(1)。当我删除每个孩子时,Firebase将为新的“最后”项目触发child_added,直到在截止点之后没有其他项目。

更新:如果您想在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

中使用

答案 1 :(得分:6)

在最新版本的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();
});

答案 2 :(得分:3)

您可以查看Scheduling Firebase Functions with Cron Jobs。该链接显示如何安排Firebase云功能以固定费率运行。在计划的Firebase功能中,您可以使用此线程中的其他答案来查询旧数据并将其删除。

答案 3 :(得分:2)

我有一个http触发的云功能,该功能会删除节点,具体取决于节点的创建时间和到期日期。

当我将一个节点添加到数据库时,它需要两个字段:时间戳以了解其创建时间,以及 duration 以了解要约何时到期。 / p>

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

您可以创建一个Cron作业,每隔X分钟向该函数的URL发出一次请求:https://cron-job.org/en/

但是我更喜欢运行自己的脚本,该脚本每10秒发出一次请求:

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

答案 4 :(得分:1)

如果有人也会遇到相同的问题,但是在 Firestore 中。我做了一个小脚本,首先将文档读到console.log,然后从24小时之前的收集消息中删除文档。使用https://cron-job.org/en/每24小时刷新一次网站,仅此而已。代码在下面。

var yesterday = firebase.firestore.Timestamp.now();
  yesterday.seconds = yesterday.seconds - (24 * 60 * 60);
  console.log("Test");
  db.collection("messages").where("date",">",yesterday)
      .get().then(function(querySnapshote) {
        querySnapshote.forEach(function(doc) {
          console.log(doc.id," => ",doc.data());
        });
      })
  .catch(function(error) {
        console.log("Error getting documents: ", error);
  });

  db.collection("messages").where("date","<",yesterday)
    .get().then(function(querySnapshote) {
      querySnapshote.forEach(element => {
        element.ref.delete();
      });
    })