将多张图片上传到 firebase,然后将图片网址保存到 firestore

时间:2021-01-17 14:28:30

标签: reactjs firebase google-cloud-firestore firebase-storage

有人可以帮助我修改代码,以便它等待上传完成然后将图片网址保存到 firestore 吗?我是异步和等待的新手,似乎无法弄清楚。即使我在 fileDownloadUrl 中保存到 firestore,Promise.all(promises).then() 仍然是空的:

cxonst promises = [];
const fileDownloadUrl = [];

pictures.forEach(file => {
    const uploadTask = 
    firebase
    .storage()
    .ref()
    .child(`img/upl/${file.data.name}`)
    .put(file.uploadTask);
    
    promises.push(uploadTask);

    uploadTask.on(
        
        firebase.storage.TaskEvent.STATE_CHANGED,
        snapshot => {
            const progress = Math.round((snapshot.bytesTransferred / 
                 snapshot.totalBytes) * 100);
            
            if (snapshot.state === firebase.storage.TaskState.RUNNING) {
                console.log(`Progress: ${progress}%`);
            }
        },
        error => console.log(error.code),
        async () => {
            const downloadURL = await 
            uploadTask.snapshot.ref.getDownloadURL();
            fileDownloadUrl.push(downloadURL);
            }
        );
    });

    Promise.all(promises)
    .then(() => {
        db
        .collection("properties")
        .add({
            timestamp: firebase.firestore.FieldValue.serverTimestamp(),
            title: title,
            description: description,
            pictures: fileDownloadUrl,
            user: user.uid
        })
    })
    .catch(err => console.log(err));

1 个答案:

答案 0 :(得分:1)

当您等待 put 调用的承诺完成时,您正在使用 uploadTask.on() 来确定下载 URL。由于此 on 不是承诺的一部分,因此无法保证它们是同步的。

更简单有效的方法应该是:

const promises = pictures.map(file => {
  const ref = firebase.storage().ref().child(`img/upl/${file.data.name}`);
  return ref
    .put(file.uploadTask)
    .then(() => ref.getDownloadURL())
});

Promise.all(promises)
.then((fileDownloadUrls) => {
    db
    .collection("properties")
    .add({
        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
        title: title,
        description: description,
        pictures: fileDownloadUrls,
        user: user.uid
    })
})
.catch(err => console.log(err));