问题描述
我有一个网站上的facebook右上角的风格通知。我在那里显示最多5条最新通知。我最初使用 child_added 拉动,同样在 firebaseRef child_added 听新的通知。现在我想播放新的通知和一些新的通知声音。
唯一我无法想象的事情是如何区分何时是一个新的通知,什么时候它已经看到,又名页面重新加载?有没有其他的办法,比做一些新的财产阅读?
我四处张望,发现一些旧的答案2012年与建议limitToLast(1)这并不帮助我的情况。 href =https://stackoverflow.com/a/27693310/633154> 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不是一个函数。
我已经尝试了多个其他版本根据文档
我的结构是相同的
{
messages:{
$ messageid:{// firebase生成密钥'jqcEWLFJrl1eaed5naN'
sender:kato,
message:hello world
timestamp:1433036536108 // Firebase.ServerValue.TIMESTAMP
}
}
}
这是我试图做的和我得到的错误:
$ b $ c $ var queryRef = notifRef。 orderByKey()。startAt(Firebase.ServerValue.TIMESTAMP);
错误:查询:键,传递给startAt(),endAt()或equalTo()的参数必须是一个字符串
var queryRef = notifRef.orderByChild('timestamp')。startAt(Firebase.ServerValue.TIMESTAMP);
错误:查询:传递给第一个参数startAt(),endAt()或equalTo()不能是一个对象。
在文档中我没有看到要启动任何东西但元素的位置传递(整数),而不是一个firebase timestamp对象,这就是为什么这样的错误。
只有在下面编译,只有startAt没有排序,但它不是拍摄任何新的通知!
var queryRef = notifRef.startAt(Firebase.ServerValue.TIMESTAMP);
queryRef.on('child_added',function(snap){
console.log(snap.val());
addNotifications(snap.val());
/ / TODO清理超过5个通知
});
有什么想法可能是问题所在?什么是正确的方式只听新的通知比当前时间戳?
编辑3
这是我的最终解决方案
$ b $ pre $ not code notifRef.limitToLast(5).once(值,函数(快照){
var lastKey = null; //至少有一个键总是存在
var count = 0; //因为startAt是包含的,我们必须忽略第一个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清理超过5个通知
checkNotifications();
}
count ++;
});
});
我不信任浏览器时间,所以不得不先查询最后5个现有的键,之后传递给 startAt 我收到的最后一个键。 notifRef.orderByKey()。startAt(lastKey)不能超出 notifRef.limitToLast(5).once(value,因为根据doc,一次最后被查询,所以 lastKey js变量传递给 startAt 将始终为空。
还需要 count 变量,因为 startAt 正在采取包容性,但因为它已经在那里,我需要忽略第一个。
也有这个解决方案,当有超过5个通知,我查询我的后端 checkNotifications 最后一次收到通知时,一次查询,否则在 child_added 它会在每次页面加载时达到5次。
如果有什么可以优化的,请告诉
解决方法之一是让您的本地客户端通过 ref.limitToLast(5).on ( child_added',...),然后只在每个通知上的某个时间戳字段比机器上的本地时间戳更新时才呈现给用户。当从其他客户端写入这些通知时,可以通过 Firebase.ServerValue.TIMESTAMP 指定一个时间戳字段,将使用服务器的Unix时间戳的概念。这些数据的读者可以比较这个时间戳到他们的本地时钟,做出上述的判断。
I have on a website facebook style notification in top right corner. I show there up to 5 latest notifications. I do initial pulling with child_added and also after same firebaseRef child_added listening for new notifications.
Now I'd like to play a sound on new notification and a little number of new notifications.
The only thing I can't figure is how to distinguish when was a new notification and when was it already seen, a.k.a page reload? Is there any other approach than making some new property read?
I was looking around and found some old answers from 2012 with suggestions limitToLast(1) which doesn't help in my case.
EDIT:
https://stackoverflow.com/a/27693310/633154 This @Kato answers recommends to listen only to new notifications which time is more than current Firebase time Firebase.ServerValue.TIMESTAMP. This seems the way to go, but I am creating a new notification with REST API and myself setting timestamp as my server's UTC. So there may be some minor inconsistencies. Shouldn't be a big deal
EDIT 2:
With this query, I'm getting correctly up to 5 last notifications on page load and no new notifications are coming afterwards
notifRef.limitToLast(5).once("value", function(snapshot) { snapshot.forEach(function(data) { addNotifications(data.val()); }); });
In the above linked other SO thread @Kato's answer doesn't work, notifRef.orderBy is not a function.
I have tried multiple other versions according to doc
https://www.firebase.com/docs/web/guide/retrieving-data.html#section-queries
My structure is same
{ "messages": { "$messageid": { // firebase generated key 'JqcEWLFJrl1eaed5naN' "sender": "kato", "message": "hello world" "timestamp": 1433036536108 // Firebase.ServerValue.TIMESTAMP } } }
Here is what i tried to do and errors I'm getting:
var queryRef = notifRef.orderByKey().startAt(Firebase.ServerValue.TIMESTAMP);
Error: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);
Error: Query: First argument passed to startAt(), endAt(), or equalTo() cannot be an object.
In the documentation I have not seen that to startAt anything but the element position is passed (integer) but not a firebase timestamp object, that's why such error.
Only below compiles, just having startAt without ordering, but it's not shooting any new notifications!
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 });
Any idea where could be the problem? What is the correct way to listen only to newer notifications than current timestamp?
EDIT 3
Here is my final solution
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++; }); });
I don't trust browser time, so had to go first by querying last 5 existing keys, and after that passing to startAt the last key I received. notifRef.orderByKey().startAt(lastKey) can't be outside notifRef.limitToLast(5).once("value" because according to doc, once is queried last so the lastKey js variable passed to startAt would be always null.
Also need to have the count variable, because startAt is taking inclusive, but because it was already there, I need to ignore the first one.
Also with this solution when there are more than 5 notifications, I query my backend with checkNotifications only once at the end when notifications are received with once query. Otherwise on child_added it would do up to 5 times on every page load.
If there is anything that could be optimized, please tell
One solution would be to have your local client listen for the last 5 latest notifications via ref.limitToLast(5).on('child_added', ...) and then only render them to the user if some timestamp field on each of those notifications is newer than your local timestamp on the machine.
When writing those notifications from other clients, you could include a timestamp field as specified via Firebase.ServerValue.TIMESTAMP, which will use the server's notion of the Unix timestamp. Readers of that data could then compare that timestamp to their local clock to make the aforementioned determination.
这篇关于只获取新的“添加的孩子”在页面加载之后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!