使用Firebase的Firestore在Vue JS中更新文档时遇到问题

时间:2018-11-26 11:54:17

标签: firebase vue.js google-cloud-firestore

我正在使用Vue JS(Vue Cli 3)和Firebase的Firestore作为后端数据库来构建一个简单的单页Web应用程序。我设法轻松地添加和删除记录。尝试“更新”用户的详细信息时遇到问题。

我为此功能编写的代码如下:

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.form.email中的“ this”在forEach循环内不可用。
  • 我认为可能是这种情况,因此我在循环之前声明了'const vm = this'并尝试使用vm.form.email,但没有骰子。
  • 此外,当我尝试将电子邮件字段更新为简单的字符串(例如“ abc”)而不是诸如this.form.email之类的动态值时,它仍然有效!

在这个荒谬的问题上花了几个小时之后,我才正式受挫。请发送帮助!

谢谢。

1 个答案:

答案 0 :(得分:1)

TL; DR :OP正在更新具有相同值的记录,因此Firestore数据库中似乎没有任何变化。但是,在他的代码中,需要返回单个异步操作(或一组异步操作)返回的promise。

由于您可能潜在地要对数据库并行执行几个异步操作(使用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()返回的promise,如下所示:

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的SAME值进行更新。因此,正常情况下您看不到任何结果。只需尝试使用另一个值进行更新,例如以下代码:

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)
        })
    }