在 firebase 存储中一次上传多张照片并将它们的 URL 存储在 firestore 文档中(firebase 版本 9)

Uploading multiple photos at once in firebase storage and storing their URLs in a firestore document (firebase version 9)

我正在构建一个表单,用户需要在其中输入信息以创建城市文档。用户还需要上传多张城市照片。提交表单时,会在 firestore 中创建一个新的城市文档,然后将每张照片上传到关联的 firebase 存储,最后将一个名为 photosURLs 的包含所有照片 URL 的新字段添加到城市文档中。

这是我的代码:

async function addDocument() {
    const docRef = await addDoc(collection(db, "cities"), {
        name: "Tokyo",
        country: "Japan"
      });
    return docRef
}

async function UploadMultiplePhotos(docRef) {
    var photos = []
    for (var i = 0; i < files.value.length; i++) { // files.values contains all the files objects
        const file = files.value[i];
        refStorageFunction(
            storage,
            "cities/" +
            docRef.id +
            "/" +
            file.name
          );
        uploadBytes(storageRef, file).then((snapshot) => {
            getDownloadURL(snapshot.ref).then((downloadURL) => {
                photos.push(downloadURL)
            });
        });
    }
    return Promise.resolve(photos)
}

async function updateDocument(docRef, photos) {
    await updateDoc(docRef, { photosURLs: photos });
}

function createCity() {
    addDocument().then((docRef) => {
        UploadMultiplePhotos(docRef).then((photos) => {
            updateDocument(docRef, photos).then(() => {
                router.push($CITY_PATH)
            })
        })
    })
}

我的问题是城市文档中生成的 photosURLs 字段为空。看来我的函数 UploadMultiplePhotos 没有等待 photos 数组完全填充。

如果您在调试器中设置断点和 运行 代码,或者添加一些适当的日志语句,您会看到 return Promise.resolve(photos) 运行 位于 photos.push(downloadURL) 曾经被调用过:所以你总是用一个空数组来解析。

一个简单的解决方案是使用 await 而不是 then():

async function UploadMultiplePhotos(docRef) {
    var photos = []
    for (var i = 0; i < files.value.length; i++) { // files.values contains all the files objects
        const file = files.value[i];
        refStorageFunction(
            storage,
            "cities/" +
            docRef.id +
            "/" +
            file.name
          );
        const snapshot = await uploadBytes(storageRef, file)
        const downloadURL = await getDownloadURL(snapshot.ref)
        photos.push(downloadURL)
    }
    return photos
}