【问题标题】:Limit number of records in firebase限制firebase中的记录数
【发布时间】:2017-09-14 06:02:04
【问题描述】:

我每分钟都有一个脚本在我的 firebase 数据库中推送一条新记录。

我想要的是当列表长度达到固定值时删除最后的记录。

我浏览过文档和其他帖子,到目前为止我发现的东西是这样的:

// Max number of lines of the chat history.
const MAX_ARDUINO = 10;

exports.arduinoResponseLength = functions.database.ref('/arduinoResponse/{res}').onWrite(event => {
  const parentRef = event.data.ref.parent;
  return parentRef.once('value').then(snapshot => {
    if (snapshot.numChildren() >= MAX_ARDUINO) {
      let childCount = 0;
      let updates = {};
      snapshot.forEach(function(child) {
        if (++childCount <= snapshot.numChildren() - MAX_ARDUINO) {
          updates[child.key] = null;
        }
      });
      // Update the parent. This effectively removes the extra children.
      return parentRef.update(updates);
    }
  });
});

问题是:onWrite似乎每次触发都会下载所有相关数据。

当列表不是很长时,这是一个非常好的过程。但是我有 4000 条记录,而且似乎每个月我都用它搞砸了我的 firebase 下载配额。

有没有人知道如何处理这种情况?

【问题讨论】:

  • 考虑单独计算所有记录并使用它来确定要删除的记录数,使用查询限制来仅查找应删除的记录。
  • 是的,这似乎是最好的选择。但是,如果不可能在整个列表上触发,如何使该计数器保持最新状态?可能是特定节点上的 onCreate 和 onDelete 与 '/arduinoResponse/{res}' 的组合?
  • 是的,onCreate 和 onDelete 可能工作得很好。还请考虑您应该使用事务来防止对某个位置的并发写入发生冲突。

标签: javascript firebase firebase-realtime-database google-cloud-functions


【解决方案1】:

好的,最后我带来了 3 个功能。一个更新arduino记录的数量,如果计数器丢失,一个完全重新计算。最后一个使用计数器使用 limitToFirst 过滤器进行查询,因此它只检索要删除的相关数据。

它实际上是 Firebase 提供的这两个示例的组合: https://github.com/firebase/functions-samples/tree/master/limit-children https://github.com/firebase/functions-samples/tree/master/child-count

这是我的最终结果

const MAX_ARDUINO = 1500;

exports.deleteOldArduino = functions.database.ref('/arduinoResponse/{resId}/timestamp').onWrite(event => {
    const collectionRef = event.data.ref.parent.parent;
    const countRef = collectionRef.parent.child('arduinoResCount');


    return countRef.once('value').then(snapCount => {
        return collectionRef.limitToFirst(snapCount.val() - MAX_ARDUINO).transaction(snapshot => {
            snapshot = null;
            return snapshot;
        })
    });
});



exports.trackArduinoLength = functions.database.ref('/arduinoResponse/{resId}/timestamp').onWrite(event => {
    const collectionRef = event.data.ref.parent.parent;
    const countRef = collectionRef.parent.child('arduinoResCount');

    // Return the promise from countRef.transaction() so our function 
    // waits for this async event to complete before it exits.
    return countRef.transaction(current => {
        if (event.data.exists() && !event.data.previous.exists()) {
            return (current || 0) + 1;
        } else if (!event.data.exists() && event.data.previous.exists()) {
            return (current || 0) - 1;
        }
    }).then(() => {
        console.log('Counter updated.');
    });
});


exports.recountArduino = functions.database.ref('/arduinoResCount').onWrite(event => {
    if (!event.data.exists()) {
        const counterRef = event.data.ref;
        const collectionRef = counterRef.parent.child('arduinoResponse');

        // Return the promise from counterRef.set() so our function 
        // waits for this async event to complete before it exits.
        return collectionRef.once('value')
            .then(arduinoRes => counterRef.set(arduinoRes.numChildren()));
    }
});

我还没有测试,但很快我会发布我的结果!

我还听说有一天 Firebase 会添加一个“大小”查询,这在我看来肯定是缺失的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 2017-09-18
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多