我在右上角的网站上发布了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次。
如果有任何可以优化的内容,请告诉
答案 0 :(得分:3)
一种解决方案是让您的本地客户端通过ref.limitToLast(5).on('child_added', ...)
侦听最近5个最新通知,然后仅在每个通知上的某个时间戳字段 newer 超过机器上的本地时间戳。
从其他客户端编写这些通知时,您可以包含通过Firebase.ServerValue.TIMESTAMP
指定的时间戳字段,该字段将使用服务器的Unix时间戳概念。然后,该数据的读者可以将该时间戳与其本地时钟进行比较,以进行上述确定。