Событие обновления Firestore onSnapshot связано с тем, что установлен локальный клиент? - PullRequest
0 голосов
/ 05 мая 2018

Простая версия: Когда я регистрируюсь на onSnapshot в Firestore, есть ли способ узнать, являюсь ли я клиентом, который выдвинул обновление?

Подробная версия:
Когда веб-страница открыта, она регистрирует обратный вызов onSnapshot в коллекцию Firestore с именем notes. Затем коллекция загружается и сохраняется в локальном массиве var notes = [].

var window.notes = []
let notesRef = refs.db.collection('notes')
notesRef.onSnapshot(querySnapshot => {
  querySnapshot.docChanges.forEach((docChange) => {
    switch (docChange.type) {
      case 'added':
        notes.push(docChange.doc.data())
        break
    }
  })
}

Затем мы обновляем заметку локально и отправляем ее в базу данных.

notes[0] =  'changed contents'
firestore.notesRef.doc(0).set(notes[0])

Это отправит заметку в firestore, обновит ее в удаленной базе данных, затем, поскольку мы зарегистрированы на onSnapshot для коллекции notes, мы запустим это событие и получим изменение modified.

let notesRef = refs.db.collection('notes')
notesRef.onSnapshot(querySnapshot => {
  querySnapshot.docChanges.forEach((docChange) => {
    switch (docChange.type) {
      case 'added':
        notes.push(docChange.doc.data())
        break
      case 'modified':
        // ********** We end up here!!! ***********
        // Probably want to do:
        notes[docChange.doc.id] = docChange.doc.data()
        break
    }
  })
}

Есть ли способ обнаружить, если этот самый клиент назвал set, который вызвал modified docChange?
Суть в том, что: если пользователь внес изменение самостоятельно, то ему не нужно заботиться об изменении объявления, мы должны его игнорировать. Если другой пользователь внес изменения, ему следует предоставить выбор, хотят ли они обновить свою локальную версию.

По моему опыту, когда вызывается firestore.notesRef.doc(0).set(notes[0]), требуется некоторое время, чтобы получить обновление с сервера. Если локальный пользователь изменяет заметку снова в это время, но еще не отправил ее на сервер, тогда его изменения теряются (переопределяются версией сервера - версией, которую они в последний раз отправили на сервер). По сути, это состояние гонки.

Итак, когда я регистрируюсь на onSnapshot в Firestore, есть ли способ узнать, являюсь ли я клиентом, который выдвинул обновление?

1 Ответ

0 голосов
/ 05 мая 2018

Вы можете увидеть, было ли это локальное или удаленное изменение с помощью:

docChange.doc.metadata.hasPendingWrites

Если hasPendingWrites равно true, то источник обновления был локальным. Локальный кэш обновлен, и запись на сервер все еще не завершена. Если hasPendingWrites равно false, источник обновления был удаленным.

Посмотрите, как его можно использовать с onSnapshot в этом фрагменте:

let notesRef = refs.db.collection('notes')
notesRef.onSnapshot(querySnapshot => {
  querySnapshot.docChanges.forEach((docChange) => {
    switch (docChange.type) {
      case 'added':
        notes.push(docChange.doc.data())
        break
      case 'modified':
        // ********** New Code ***********
        let source = docChange.doc.metadata.hasPendingWrites ? 'Local' : 'Server'
        if (source === 'Server') {
          notes[docChange.doc.id] = docChange.doc.data()
        } else {
          // Do nothing, it's a local update so ignore it
        }
        // ********** New Code End ***********
        break
    }
  })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...