只获得新的"加入儿童"页面加载后

时间:2015-05-27 21:47:04

标签: javascript firebase

我在右上角的网站上发布了Facebook样式通知。我在那里显示最多5个最新通知。我首先使用child_added并在同一firebaseRef child_added听取新通知后进行初步调整。

现在我想在新通知和一些新通知上播放声音 我唯一能做的就是如何区分何时是新通知以及何时已经看到,a.k.a页面重新加载?除了制作一些新属性read之外还有其他方法吗?

我环顾四周,发现了2012年的一些旧答案,并提出了限制至少(1)的建议,这对我的情况没有帮助。

编辑:

https://stackoverflow.com/a/27693310/633154此@Kato答案建议仅收听时间超过当前Firebase时间Firebase.ServerValue.TIMESTAMP的新通知。这似乎是要走的路,但我正在创建一个使用REST API的新通知,我自己将时间戳设置为我的服务器的UTC。因此可能存在一些轻微的不一致。不应该是一个大问题

编辑2:

通过此查询,我在页面加载时最多可以获得5个最后通知,之后不会有新通知

notifRef.limitToLast(5).once("value", function(snapshot) {
    snapshot.forEach(function(data) {
        addNotifications(data.val());
    });
});

在上面链接的其他SO帖子中,@ Kato的答案不起作用notifRef.orderBy is not a function
我根据文件
试过了多个其他版本 https://www.firebase.com/docs/web/guide/retrieving-data.html#section-queries

我的结构相同

{
  "messages": {
     "$messageid": { // firebase generated key 'JqcEWLFJrl1eaed5naN'
        "sender": "kato",
        "message": "hello world"
        "timestamp": 1433036536108  // Firebase.ServerValue.TIMESTAMP
     }
  }
}

以下是我尝试做的事情以及我得到的错误:

var queryRef = notifRef.orderByKey().startAt(Firebase.ServerValue.TIMESTAMP);
错误:Query: When ordering by key, the argument passed to startAt(), endAt(),or equalTo() must be a string.

var queryRef = notifRef.orderByChild('timestamp').startAt(Firebase.ServerValue.TIMESTAMP);
错误:Query: First argument passed to startAt(), endAt(), or equalTo() cannot be an object.

在文档中我没有看到启动除了元素位置传递(整数)而不是firebase时间戳对象,这就是为什么会出现这样的错误。

仅在下面编译,只是在没有订购的情况下启动它,但它没有拍摄任何新的通知!

var queryRef = notifRef.startAt(Firebase.ServerValue.TIMESTAMP);
queryRef.on('child_added', function(snap) {
    console.log(snap.val());
    addNotifications(snap.val());
    // TODO clean up if more than 5 notifications
});

知道问题出在哪里?仅收听比当前时间戳更新的通知的正确方法是什么?

编辑3

这是我的最终解决方案

notifRef.limitToLast(5).once("value", function(snapshot) {
    var lastKey = null; // at least 1 key is always present
    var count = 0; // because startAt is inclusive, we have to ignore first child_added
    snapshot.forEach(function(data) {
        addNotifications(data.val());
        lastKey = data.key();
    });
    checkNotifications();
    notifRef.orderByKey().startAt(lastKey).on('child_added', function(snap) {
        if (count > 0) {
            console.log(snap.val());
            addNotifications(snap.val());
            // TODO clean up if more than 5 notifications
            checkNotifications();
        }
        count++;
    });
});

我不相信浏览器时间,因此必须先查询最后5个现有密钥,然后转到startAt我收到的最后一个密钥。 notifRef.orderByKey().startAt(lastKey)不能在notifRef.limitToLast(5).once("value"之外,因为根据文档,最后查询once,因此传递给lastKey的{​​{1}} js变量始终为null 。
还需要拥有startAt变量,因为count正在考虑包容性,但由于它已经存在,我需要忽略第一个变量。
此外,当有超过5个通知的时候,我使用startAt只在结束时通过checkNotifications查询收到通知时查询我的后端。否则,在once上,每次加载页面时最多会执行5次。

如果有任何可以优化的内容,请告诉

1 个答案:

答案 0 :(得分:3)

一种解决方案是让您的本地客户端通过ref.limitToLast(5).on('child_added', ...)侦听最近5个最新通知,然后仅在每个通知上的某个时间戳字段 newer 超过机器上的本地时间戳。

从其他客户端编写这些通知时,您可以包含通过Firebase.ServerValue.TIMESTAMP指定的时间戳字段,该字段将使用服务器的Unix时间戳概念。然后,该数据的读者可以将该时间戳与其本地时钟进行比较,以进行上述确定。