页面加载后仅获取新的 "child added"
Get only new "child added" after page load
我在网站的右上角有 facebook 风格的通知。我在那里显示 最多 5 个最新通知。我用 child_added
进行初始拉动,并且在相同的 firebaseRef
child_added
之后监听新通知。
现在我想在收到新通知和少量新通知时播放声音。
我唯一想不通的是如何区分什么时候是新通知,什么时候已经看到,a.k.a 页面重新加载?除了制作一些新的 属性 read
之外还有其他方法吗?
我环顾四周,发现了 2012 年的一些旧答案以及建议 limitToLast(1),这对我的情况没有帮助。
编辑:
这个@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
。
根据 doc
我已经尝试了多个其他版本
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.
在文档中我没有看到 startAt 除了元素位置被传递(整数)而不是 firebase 时间戳对象之外的任何东西,这就是为什么这样的错误。
只有 below 编译,只是有 startAt 而没有排序,但它没有发射任何新通知!
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
因此传递给 startAt
的 lastKey
js 变量将始终为 null。
还需要有 count
变量,因为 startAt
是包容性的,但因为它已经存在,所以我需要忽略第一个。
此外,当有超过 5 个通知时使用此解决方案,当收到 once
查询通知时,我只在最后一次使用 checkNotifications
查询我的后端。否则在 child_added
上它会在每次页面加载时执行多达 5 次。
如果有什么可以优化的,请告诉
一个解决方案是让您的本地客户端通过 ref.limitToLast(5).on('child_added', ...)
收听最近 5 条最新通知,然后仅在每个通知上的某个时间戳字段为 时才将它们呈现给用户 比机器上的本地时间戳更新。
当从其他客户端写入这些通知时,您可以包含通过 Firebase.ServerValue.TIMESTAMP
指定的时间戳字段,这将使用服务器的 Unix 时间戳概念。然后,该数据的读者可以将该时间戳与他们的本地时钟进行比较,以做出上述决定。
我在网站的右上角有 facebook 风格的通知。我在那里显示 最多 5 个最新通知。我用 child_added
进行初始拉动,并且在相同的 firebaseRef
child_added
之后监听新通知。
现在我想在收到新通知和少量新通知时播放声音。
我唯一想不通的是如何区分什么时候是新通知,什么时候已经看到,a.k.a 页面重新加载?除了制作一些新的 属性 read
之外还有其他方法吗?
我环顾四周,发现了 2012 年的一些旧答案以及建议 limitToLast(1),这对我的情况没有帮助。
编辑:
这个@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
。
根据 doc
我已经尝试了多个其他版本
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.
在文档中我没有看到 startAt 除了元素位置被传递(整数)而不是 firebase 时间戳对象之外的任何东西,这就是为什么这样的错误。
只有 below 编译,只是有 startAt 而没有排序,但它没有发射任何新通知!
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
因此传递给 startAt
的 lastKey
js 变量将始终为 null。
还需要有 count
变量,因为 startAt
是包容性的,但因为它已经存在,所以我需要忽略第一个。
此外,当有超过 5 个通知时使用此解决方案,当收到 once
查询通知时,我只在最后一次使用 checkNotifications
查询我的后端。否则在 child_added
上它会在每次页面加载时执行多达 5 次。
如果有什么可以优化的,请告诉
一个解决方案是让您的本地客户端通过 ref.limitToLast(5).on('child_added', ...)
收听最近 5 条最新通知,然后仅在每个通知上的某个时间戳字段为 时才将它们呈现给用户 比机器上的本地时间戳更新。
当从其他客户端写入这些通知时,您可以包含通过 Firebase.ServerValue.TIMESTAMP
指定的时间戳字段,这将使用服务器的 Unix 时间戳概念。然后,该数据的读者可以将该时间戳与他们的本地时钟进行比较,以做出上述决定。