Возникли проблемы при обновлении документа в Vue JS с помощью Firebase's Firestore - PullRequest
0 голосов
/ 26 ноября 2018

Я создаю простое одностраничное веб-приложение, использующее Vue JS (Vue Cli 3) с Firestore Firebase в качестве внутренней базы данных.Мне удалось добавить и удалить записи с легкостью.Я сталкиваюсь с проблемой при попытке «обновить» данные пользователя.

Мой код этой функции выглядит следующим образом:

saveEditUser() {
  db.collection('users')
    .where('email', '==', this.form.email)
    .get()
    .then(snap => {
      snap.forEach(doc => {
        doc.ref.update({
          email: this.form.email
        })
      })
    })
    .then(() => {
      console.log('Successfully updated the record')
    })
    .catch(error => {
      console.error('There was an error editing the record: ' + error)
    })
}

Некоторые вещи, которые я обнаружил во время моегопопытки отладки этого:

  • Это , а не проблема с областью, где 'this' в this.form.email недоступно внутри цикла forEach.
  • Я думал, что это может быть так, и поэтому я объявил 'const vm = this' перед циклом и попытался использовать vm.form.email, но без кубиков.
  • Кроме того, когда я пытаюсь обновитьполе электронной почты в простую строку, такую ​​как 'abc', вместо динамического значения, такого как this.form.email, оно работает!

После нескольких часов, проведенных за этой нелепой проблемой, я официально поставлен в тупик.Пожалуйста, пришлите помощь!

Спасибо.

1 Ответ

0 голосов
/ 26 ноября 2018

TL; DR : OP обновлял запись с тем же значением, поэтому в базе данных Firestore ничего не изменилось.Однако в его коде была необходимость вернуть обещание, возвращаемое одной асинхронной операцией (или набором асинхронных операций)

, поскольку вы потенциально собираетесьвыполнить несколько асинхронных операций с базой данных параллельно (используя метод update(), который возвращает обещание, см. doc ), вам нужно использовать Promise.all () , как показано ниже.

saveEditUser() {
  const email = this.form.email;
  const= promises = [];
  db.collection('users')
    .where('email', '==', email )
    .get()
    .then(snap => {
      snap.forEach(doc => {
        promises.push(
            doc.ref.update({
                email: email   //Actually the problems comes from here, see below
             })
        );
        return Promise.all(promises);
      })
    })
    .then(() => {
      console.log('Successfully updated the record')
    })
    .catch(error => {
      console.error('There was an error editing the record: ' + error)
    })
}

Если вы на 100% уверены, что ваш запрос вернет только один документ, вы можете обновить документ напрямую, но затем вы должны вернуть обещание, возвращенное update(), следующим образом:

saveEditUser() {
  const email = this.form.email;
  db.collection('users')
    .where('email', '==', email)
    .get()
    .then(snap => {
      return snap.docs[0].ref.update({
          email: email
        });
    })
    .then(() => {
      console.log('Successfully updated the record')
    })
    .catch(error => {
      console.error('There was an error editing the record: ' + error)
    })
}

Примечание: объявив константу email в начале функции, вы больше не столкнетесь с проблемой контекста.


Обновите после наших комментариев и обсуждений:

На самом деле вы обновляете то же самое значение email.Так что это нормально, вы не видите никакого результата.Просто попробуйте обновить с другим значением, как в следующем коде:

saveEditUser() {
  const email = this.form.email;
  db.collection('users')
    .where('email', '==', email)
    .get()
    .then(snap => {
      return snap.docs[0].ref.update({
          email: 'john.doe@gmail.com'
        });
    })
    .then(() => {
      console.log('Successfully updated the record')
    })
    .catch(error => {
      console.error('There was an error editing the record: ' + error)
    })
}

Если вы хотите проверить со значением из вашей формы, просто используйте два поля: одно со значением для запроса и одно сновое значение, например:

<input v-model="form.mail" placeholder="mail to search for">
<input v-model="form.newMail" placeholder="new email">

.....

    saveEditUser() {
      const emailToQuery = this.form.email;
      const newEmail = this.form.newMail;
      db.collection('users')
        .where('email', '==', emailToQuery )
        .get()
        .then(snap => {
          return snap.docs[0].ref.update({
              email: newEmail 
            });
        })
        .then(() => {
          console.log('Successfully updated the record')
        })
        .catch(error => {
          console.error('There was an error editing the record: ' + error)
        })
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...