Javascript 侦听器和实际添加数据的客户端之间未同步Firebase.ServerValue.TIMESTAMP

Javascript 侦听器和实际添加数据的客户端之间未同步Firebase.ServerValue.TIMESTAMP,javascript,timestamp,firebase,Javascript,Timestamp,Firebase,以下是可能的最简单示例: var fb = new Firebase('https://xxxxxxxxxxx.firebaseio.com/test'); fb.limitToLast(1).on('child_added', function(snap) { console.log('key', snap.key()); console.log('val', snap.val()); }); fb.push({ date_now: Firebase.ServerV

以下是可能的最简单示例:

var fb = new Firebase('https://xxxxxxxxxxx.firebaseio.com/test');

fb.limitToLast(1).on('child_added', function(snap) {
    console.log('key', snap.key());
    console.log('val', snap.val());
});

fb.push({
    date_now: Firebase.ServerValue.TIMESTAMP
});
如果我用这个脚本打开两个选项卡,实际推送数据的选项卡在child_added callback中获得local时间戳,而仅侦听的另一个选项卡获得正确的服务器生成的时间戳。据我所知,这样做是为了避免往返,节省带宽

但就我的任务而言,这种行为是不可接受的。我怎样才能克服它

这是pusher提供的console.log:

key -K59mrvEUhTaoNIQQoA4
val Object {date_now: 1449732570832}
和侦听器(等于仪表板中显示的服务器数据):


对于实时SDK,这是预期的行为。最后,时间戳将反映正确的服务器值。但是,如果这不适合您的需要,您可以使用RESTAPI

function addTimestamp() {
  fetch('https://<my-firebase-app>.firebaseio.com/test/.json', {
    method: 'post',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      '.sv': 'timestamp' // add a timestamp
    })
  });
}
函数addTimestamp(){
取('https://.firebaseio.com/test/.json', {
方法:“post”,
标题:{
“接受”:“应用程序/json”,
“内容类型”:“应用程序/json”
},
正文:JSON.stringify({
'.sv':'timestamp'//添加时间戳
})
});
}

这将不使用本地时间戳,并且与实时SDK结合使用时,每个客户端在第一次更新时将具有相同的时间戳。

Firebase为该写入操作触发两个本地事件:

  • 它会立即触发一个带有本地时间戳的
    child\u added
    事件(针对您预期的服务器偏移量进行了更正)
  • 它随后会触发一个
    child\u changed
    事件,事件具有服务器指定的实际时间戳
  • 因此,您可以通过监听两个事件来解决问题:

    var fb = new Firebase('https://xxxxxxxxxxx.firebaseio.com/test');
    
    var query = fb.limitToLast(1);
    query.on('child_added', function(snap) {
        console.log('key', snap.key());
        console.log('val', snap.val());
    });
    query.on('child_changed', function(snap) {
        console.log('key', snap.key());
        console.log('val', snap.val());
    });
    
    fb.push({
        date_now: Firebase.ServerValue.TIMESTAMP
    });
    
    通常,建议处理所有
    child.*
    事件,而不仅仅是添加的
    child.
    。服务器必须更新或删除该值以更正本地事件的原因可能更多

    如果您喜欢使用单个回调/事件处理程序,还可以侦听
    事件:

    var query = fb.limitToLast(1);
    query.on('value', function(snap) {
        snap.forEach(function(child) {
            console.log('key', child.key());
            console.log('val', child.val());
        });
    });
    

    您将注意到在回调中使用了
    forEach()

    监听“child\u changed”解决了这个问题。谢谢!谢谢你的解释,弗兰克!在这种情况下,我是否可以确保添加的child_返回的值始终与更改的child_返回的值不同?否。如果没有时钟偏移,则来自服务器的值将相同。这不太可能,但也可能发生。@FrankvanPuffelen在相同的情况下,是否仍激发了child_changed?如果值相同,则该子级未发生更改,因此不会激发
    child_changed
    事件。
    var query = fb.limitToLast(1);
    query.on('value', function(snap) {
        snap.forEach(function(child) {
            console.log('key', child.key());
            console.log('val', child.val());
        });
    });