删除超过 2 小时的 Firebase 数据

IT技术 javascript angularjs firebase firebase-realtime-database
2021-01-17 17:25:03

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

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

5个回答

Firebase 不支持带有动态参数的查询,例如“两小时前”。但是,可以对特定值执行查询,例如“after August 14 2015, 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();
});

正如您会注意到的,我使用child_added代替value, 和 I 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-samplesrepo 中找到

在您的示例中,您获取 2 小时前或更短时间保存的记录。也许您应该使用 endAt 而不是 startAt。但是还是谢谢你的回答对我有帮助
2021-03-10 17:25:03
嗨,弗兰克,我正在尝试在 Swift 中做类似的事情,但是我似乎无法弄清楚您在侦听器中调用的方法。我花了几个小时搜索和尝试,但决定是时候寻求帮助了!
2021-03-24 17:25:03
从 iOS 上传时间戳的任何人请注意:timeIntervalSince1970 以秒为单位,Date.now() 为毫秒,因此请确保根据需要进行转换
2021-04-02 17:25:03
接得好!固定的。
2021-04-03 17:25:03
当我实现这一点时,所有数据都在 1 秒而不是 2 小时后被删除。我已经完全复制并粘贴了代码,所以我不知道发生了什么?
2021-04-08 17:25:03

我有一个 http 触发的云函数可以删除节点,具体取决于节点的创建时间和到期日期。

当我向数据库添加一个节点时,它需要两个字段:时间戳以了解其创建时间,以及持续时间以了解优惠何时必须到期。

在此处输入图片说明

然后,我有这个 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
感谢您的工作!救命恩人!
2021-03-15 17:25:03
cronjob 是免费的吗?
2021-04-06 17:25:03

在最新版本的 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();
});
时间戳是长数字(在 firebase 上)还是时间戳类型?
2021-03-15 17:25:03
我需要 swift 4 的解决方案,任何想法!
2021-03-24 17:25:03

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

如果有人会遇到同样的问题,但在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();
      });
    })