Firebase - как определить, откуда идет onSnapshot - PullRequest
0 голосов
/ 13 декабря 2018

Я создаю простое приложение для Firebase.Основная текстовая область связана с записью в Firebase.Когда пользователь вводит, я debounce событие keyup (300 мс) и обновляю Firebase.

Каждое событие .update запускает событие onSnapshot, когда оно возвращается с сервера (котороеожидаемое поведение Firebase).Моя проблема в том, что это мешает пользователю, пока он печатает.Потому что существует задержка между временем отправки запроса на сервер и его возвратом.Когда он возвращается, пользователь уже набрал больше текста, и содержимое текстовой области отличается от того, когда был запущен .update.

Вот мой код и jsFiddle, который иллюстрирует проблему:

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 - без serverTimestamp ()

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

Я обнаружил, что удаление вызова функции serverTimestamp() очень помогает.Похоже, он отвечает за задержку запроса.Это делает «ошибку» практически незаметной, но иногда это происходит, когда выполнение запроса занимает немного больше времени.

Единственное решение, о котором я могу подумать, - это обнаружить инициатора обновления.Всякий раз, когда срабатывает событие onSnapshot, мы можем посмотреть на объект doc и сказать, было ли изменение сделано с этого клиента или с другого.Но, по-видимому, такой функции не существует.

Есть идеи, как мне решить эту проблему?

РЕДАКТИРОВАТЬ:

В итоге я увеличил задержку отката.Вместо обновления через 300 мс я жду несколько секунд.Таким образом, пользовательский ввод не может быть нарушен.Я также замораживаю текстовую область во время обновления.

1 Ответ

0 голосов
/ 13 декабря 2018

Это потому, что содержимое письменного документа может отличаться от того, что набрал пользователь с момента обновления документа.

Переосмыслить этот код:

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

Это происходитпереписать все, что пользователь ввел с момента запуска дебюта, и документ обновлялся по мере их продвижения.Это будет особенно болезненно в сетях с высокой задержкой.

Вместо этого рассмотрим , а не , переписывающую всю текстовую область при каждом изменении документа, и вместо этого показывающую индикатор состояния синхронизации их ввода.Синхронизируется или нет?Это все, что нужно знать пользователю.Вам не нужно регулярно переписывать их набор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...