使用 Firebase 更新文档字段时使用 Object.assign

Posted

技术标签:

【中文标题】使用 Firebase 更新文档字段时使用 Object.assign【英文标题】:Using Object.assign when updating document fields with Firebase 【发布时间】:2020-02-07 22:04:19 【问题描述】:

我正在创建一个用户可以创建新项目的网站。要创建项目,用户必须填写包含所有项目信息的表格。这个表单里面是一个文件输入字段,用户可以通过它选择图像和文档。我的代码循环遍历所有文件并将它们存储在 Firebase 存储中。这部分代码运行良好,除了我试图用该数据填充文档字段的部分。

我通过在 Firebase .update() 中使用 Object.assign() 进行了尝试。 每当这段代码被触发时,它就会抛出这个错误:

使用无效数据调用函数 DocumentReference.update()。不支持的字段值:自定义文件对象(在字段图像中找到)

我知道Object.assign 是这里的问题,因为没有它它也可以工作。如果有人可以帮助我解决这个问题,我将不胜感激。

这是引发错误的代码部分:

firestore.collection('projects').doc(res.id)
    .update(Object.assign(this.values, 
        createdAt: new Date(),
        updatedAt: new Date(),
        createdBy: '/users/' + firebaseApp.auth().currentUser.email,
        approved: false
    ))
    .then(res => 
       console.log(res)
       this.$toast.success('Project changes saved',  icon: 'mdi-check-bold' )
     ).catch((err) => 
         this.$toast.error(err.message,  icon: 'mdi-alert-circle' )
         console.log(err)
       )

这是我在提交时调用的函数:

submit () 
  this.overlay = true

      firestore.collection('projects').add()
          .then((res) => 
            Promise.all(
              fileKeys.map((key, index) => 
                return new Promise((resolve, reject) => 
                  if (!this.values[key]) 
                    resolve(this.values[key])
                   else 
                    if (typeof this.values[key][0] === 'undefined') 
                      const file = this.values[key]
                      const ref = storage.ref(`/projects/$res.id/$file.name`)

                      this.uploadHandler(file, ref, index).then((downloadURL) => 
                        if (downloadURL) 
                          this.values[key] = 
                            url: downloadURL,
                            fullPath: ref.fullPath,
                            name: file.name || '',
                            size: file.size || '',
                            type: file.type || ''
                          

                          resolve(this.values[key])
                         else 
                          reject()
                        
                      )

                     else 
                      const fileCollection = [];

                      Promise.all(
                        (this.values[key]).map((file) => 
                          return new Promise((resolve, reject) => 
                            const ref = storage.ref(`/projects/$res.id/$file.name`)

                            this.uploadHandler(file, ref, index).then((downloadURL) => 
                              if (downloadURL) 
                                fileCollection.push(
                                  url: downloadURL,
                                  fullPath: ref.fullPath,
                                  name: file.name || '',
                                  size: file.size || '',
                                  type: file.type || '',
                                  height: '',
                                  width: ''
                                )
                              

                              resolve(downloadURL)
                            ).catch((e) => 
                              reject(e)
                            )
                          )
                        )
                      ).then(() => 
                        this.values[key] = fileCollection.length > 0 ? fileCollection : null
                        resolve(fileCollection)
                      )
                    
                  
                )
              )
            )
            firestore.collection('projects').doc(res.id).update(Object.assign(this.values,  createdAt: new Date(), updatedAt: new Date(), createdBy: '/users/' + firebaseApp.auth().currentUser.email, approved: false ))
              .then(res => 
              console.log(res)
              this.$toast.success('Project changes saved',  icon: 'mdi-check-bold' )
            ).catch((err) => 
              this.$toast.error(err.message,  icon: 'mdi-alert-circle' )
              console.log(err)
            )
          ).catch((err) => 
            console.log(err)
            console.log('error')
          )
        ,

【问题讨论】:

【参考方案1】:

错误消息告诉您,您传递给update() 的对象包含一个文件对象作为其属性之一,这是不被接受的。您应该只将具有常见 javascript 类型、时间戳或 DocumentReferences 的对象传递给 Firestore。

这可能意味着this.values 在调用Object.assign() 之前至少包含一个文件对象。 (代码有点难以理解,所以我无法立即看到它可能是什么。)您必须做的是确保您正在编写一个不包含 File 对象的对象。如果您打算将上传的文件存储在 Cloud Firestore 中,那么这可能不是一个好主意,因为您很容易超过 1MB 的最大文档大小。

【讨论】:

感谢您的回复!有没有办法将文件对象变成 Firebase 接受的东西? 如果有的话,你将不得不确切地弄清楚你想在它的位置存储什么。我不知道你的情况会怎样。 在这方面我仍然是初学者,所以我不知道是否可行,但我想将文件对象转换为普通的 JSON 对象,以便将其存储在 Firebase 中。 我认为您应该研究读取文件并使用其内容的方法。也许从这个开始:developer.mozilla.org/en-US/docs/Web/API/FileReader

以上是关于使用 Firebase 更新文档字段时使用 Object.assign的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Firestore更新时间字段安全问题

有没有办法根据 firebase Auth 用户信息更新 firestore 文档字段?

如何通过本机反应将新字段数据更新到现有文档而不覆盖firebase-9中的现有数据

Firebase - 使用 Cloud Functions 定位特定的 Firestore 文档字段

如何使用 Firebase 云功能更新文档值

更新 Firestore 数据库中文档的字段