首页 > 解决方案 > 为什么我的 Firestore 文档的数组字段总是只更新比我从前端发送的数组少一项?

问题描述

将文件保存到 Google Cloud Storage 后,我正在尝试更新 Firestore 文档。我想将存储文件的 URL 数组发送到 Firestore 中的文档,如下所示...

(attachments: [ {url: "fileone.jpeg", ...}, {url: "filetwo.jpeg", ...}, ...]).

这个 URL 数组是在前端使用 firebases 创建的getDownloadURL()。我可以成功更新我的文档,但更新后的文档中的数组总是比前端创建的数组少一个项目。当console.log-ing 存储在内存中的数组(要发送到 firestore)时,我看到括号内的值[{},{}]也比 array.length 小一。

记录 fileUrls 数组(存储在内存中以发送到 firestore)的控制台会显示,即使fileUrls.length === 3扩展以下行显示了所有三个包含从索引 0 开始的对象的 URL:

fileUrls: > (2) [{…}, {…}]

以下是实现此更新过程的代码:

let fileUrls = [];               // <<-- Array for file urls to be stored
let promises = [];

for (const file of state.post.files) {
  const fileRef = storage.ref().child(`my file path`);
  const p = fileRef.put(file)
    .then(snapshot => {
      fileRef.getDownloadURL()
        .then(url => {
          fileUrls.push({ url: url, type: file.type })  // Adding urls to arr
        })
    })

  promises.push(p);
}

const all = Promise.all(promises);
all
  .then(() => {
    submissionRef.update({         // <<<--- Updating document created prior.
      attachments: fileUrls
    })
  })
  .catch(err => console.log(err));

标签: javascriptarraysfirebasegoogle-cloud-firestore

解决方案


您正在等待文件完成上传,但您不会等到下载 URL 被获取。您需要将 getDownloadURL 返回的承诺加入到传递给 Promise.all() 的承诺数组中。尝试从then文件上传的回调中返回它的承诺:

  const p = fileRef.put(file)
    .then(snapshot => {
      // add a return here to chain the promise returned by getDownloadURL()
      // with the promise returned by put()
      return fileRef.getDownloadURL()
        .then(url => {
          fileUrls.push({ url: url, type: file.type })  // Adding urls to arr
        })
    })

考虑改为使用 async/await 语法来避免所有这些回调并使代码更易于阅读。


推荐阅读