限制firebase中的记录数

时间:2017-09-07 20:06:24

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

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

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

我已经阅读过doc和其他帖子,到目前为止我发现的东西是这样的:

// 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下载配额。

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

1 个答案:

答案 0 :(得分:0)

好的,最后我带来了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会添加一个&#34;尺寸&#34;查询,在我看来肯定是缺失的。