Firebase-如何检测onSnapshot的来源 [英] Firebase - how to detect where the onSnapshot is coming from

查看:42
本文介绍了Firebase-如何检测onSnapshot的来源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个简单的firebase应用程序.主要文本区域链接到Firebase上的条目.当用户键入内容时,我去抖动键事件(300毫秒),然后在Firebase上进行更新.

I'm building a simple firebase app. The main textarea is linked to an entry on Firebase. When the user types, I debounce the keyup event (300ms) and I do an update on Firebase.

每个 .update 事件在从服务器返回时都会触发 onSnapshot 事件(这是Firebase的预期行为).我的问题是,它会在用户键入内容时打扰他们.因为请求到达服务器的时间与返回请求之间存在延迟.回来时,用户已经输入了更多文本,并且文本区域的内容与 .update 被触发时不同.

Every .update event triggers a onSnapshot event when it comes back from the server (which is the expected behaviour of Firebase). My problem is that it disturbs the user while they type. Because there is a delay between the time the request goes to the server and when it comes back. When it comes back the user has already typed more text and the content of the textarea is different that when the .update was fired.

这是我的代码和一个说明问题的jsFiddle:

Here's my code and a jsFiddle that illustrates the problem:

var textareaElement = document.querySelector('textarea');

// Initialize Firebase
var config = {
  apiKey: "XXX",
  authDomain: "XXX",
  projectId: "XXX",
};
firebase.initializeApp(config);
const db = firebase.firestore();
const doc = db.collection("notes").doc('XXX');

// This is debounced
const update = function(){
    doc.update({
    text: textareaElement.value,
    updated_at: firebase.firestore.FieldValue.serverTimestamp()
  })
}

// Update the server when we change the client
textareaElement.addEventListener('keyup', _.debounce(update, 300));

// Listen for changes from the server
doc.onSnapshot(function(doc){
    textareaElement.value = doc.data().text
});

jsFiddle

https://jsfiddle.net/x6h80keb/2 (以正常速度输入,会明白我的意思)

jsFiddle

https://jsfiddle.net/x6h80keb/2 (type at a normal pace and you will see what I mean)

https://jsfiddle.net/x6h80keb/6/

我发现删除对 serverTimestamp()函数的调用有很大帮助.看起来是造成请求延迟的原因.它使错误"几乎不明显,但有时仍会在请求执行时间较长时发生.

I found that removing the call to the serverTimestamp() function helps a lot. It looks like it's responsible for the delay of the request. It makes the "bug" almost unnoticeable, but it still happens sometimes, when the request takes a bit longer to execute.

我能想到的唯一解决方案是检测更新的发起者.每当触发 onSnapshot 事件时,我们都可以查看 doc 对象,并判断是从此客户端还是从另一个客户端进行了更改.但是显然没有这种功能.

The only solution I can think of would be to detect the initiator of the update. Whenever a onSnapshot event is triggered, we could look into the doc object, and tell if the change has been made from this client or from another one. But there isn't such a feature apparently.

有什么办法可以克服这个问题吗?

Any ideas how I could overcome this problem ?

我最终增加了反跳延迟.我没有等待300毫秒后更新,而是等待了几秒钟.这样,用户输入不会受到打扰.我还将在.update期间冻结文本区域.

I ended up increasing the debounce delay. Instead of updating after 300ms, I wait a few seconds. This way the user typing can not be disturbed. I'll also freeze the textarea during the .update.

推荐答案

这是因为书面文档的内容可能与自文档更新以来用户输入的内容不同.

This is because the contents of the written document may be different than what the user has typed in since the document was updated.

重新考虑以下代码:

doc.onSnapshot(function(doc){
    textareaElement.value = doc.data().text
});

这将覆盖自防抖动触发和用户使用进度更新文档以来用户键入的任何内容.在具有高延迟的网络上,这尤其令人痛苦.

This is going to overwrite whatever the user has typed since the debounce triggered and the document was updated with their progress. It will be especially painful on networks with high latency.

请考虑在每次文档更改时重写整个文本区域,而是显示一个指示其键入同步状态的指示器.他们的打字是否同步?这就是用户需要知道的全部信息.您不需要定期覆盖它们的输入.

Consider instead not rewriting the entire textarea on each document change, and instead showing an indicator for the sync status of their typing. Is their typing in sync or not? That's all the user needs to know. You don't need to overwrite their typing on a regular basis.

这篇关于Firebase-如何检测onSnapshot的来源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆