如何使用Firebase将初始数据加载与增量子级分开?

时间:2015-01-16 05:55:47

标签: firebase firebase-realtime-database

我有一个应用程序,每5秒左右就会有新的孩子被添加到Firebase。我有成千上万的孩子。

在应用程序加载时,我想要处理最初的数千个,而不是每5秒钟滴流一次的后续子项。

您可能会建议我使用值,处理所有内容,然后使用children_added。但我相信如果处理时间过长,我有可能错过一点。

有没有办法在Firebase中做到这一点,保证我不会错过任何一点?

4 个答案:

答案 0 :(得分:62)

由于初始预加载数据的child_added事件将在 value事件触发之前触发,因此您可以使用value事件作为一种“初始数据加载”通知。以下是我从another similar StackOverflow question稍微修改过的一些代码。

var initialDataLoaded = false;
var ref = new Firebase('https://<your-Firebase>.firebaseio.com');

ref.on('child_added', function(snapshot) {
  if (initialDataLoaded) {
    var msg = snapshot.val().msg;
    // do something here
  } else {
    // we are ignoring this child since it is pre-existing data
  }
});

ref.once('value', function(snapshot) {
  initialDataLoaded = true;
});

值得庆幸的是,Firebase会巧妙地缓存此数据,这意味着创建child_addedvalue侦听器只会下载一次数据。为已经越过网线的数据添加新的Firebase监听器是非常便宜的,你应该会经常做这样的事情。

如果您担心在实际不需要时下载所有初始数据,我会在评论中按照@ FrankvanPuffelen的建议使用带时间戳的查询。这非常有效,并使用Firebase查询进行了优化。

答案 1 :(得分:0)

在数据库中添加了一个createdAt时间戳,并使用当前时间限制了child_add,对我来说似乎正常。

const onChildAdded = database()
  .ref(refURL)
  .limitToLast(constValues.LAST_MESSAGE_ADDED)
  .orderByChild('createdAt')
  .startAt(date.getTime())
  .on('child_added', (snapshot) => {
    parseMessage(snapshot);
  });

database()
  .ref(refURL)
  .limitToLast(constValues.LAST_MESSAGES_LIMIT)
  .once('value', (snapshot) => {
    parseInitialMessages(snapshot);
    setLoading(false);
  });

答案 2 :(得分:-1)

改进了@jacobawenger的答案,不使用全局状态变量

var ref = new Firebase('https://<your-Firebase>.firebaseio.com');

ref.once('value', function(snapshot) {
  // do something here with initial value

  ref.on('child_added', function(snapshot) {
    // do something here with added childs
  });

});

答案 3 :(得分:-2)

这个问题有两种可能的解决方案,既不令人满意:

1)为您的孩子设定时间戳,并仅请求时间戳大于&#34;现在&#34;值。这并不是很好,因为您的应用程序之间可能存在同步问题,现在&#34;和#34;现在&#34;将数据推送到Firebase或Firebase服务器值的任何内容#34;现在&#34;。

2)使用值和子项添加。在child_added中看到的任何已经在值中看到的重复项可能会被丢弃。这对于大型数据集来说是不可用的,因为它需要下载所有历史数据TWICE!

为什么不能有&#34; child_added&#34;等命令? DOESN&T?T给了一切吗?