Firebase-如何检测onSnapshot的来源 [英] Firebase - how to detect where the onSnapshot is coming from
问题描述
我正在构建一个简单的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屋!