我有一个小应用程序,可以将图像上传到 firebase 并获取 url 来显示它们。当我上传单张图片时效果很好。但是当我尝试上传多张图片时,它并没有像我想的那样工作。它总是返回空数组,我想要像 [url1,url2,...] 这样的东西。这是我的代码: 火力基地
import { initializeApp } from "firebase/app";
import { getStorage } from "firebase/storage";
const firebaseConfig = {
apiKey: ,
authDomain: ,
projectId: ,
storageBucket: ,
messagingSenderId: ,
appId: ,
measurementId:
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const storage = getStorage(app);
myApp
import React, { useState, useEffect } from "react";
import { storage } from "../../ultis/firebase";
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
const MyApp= () => {
const [files, setFiles] = useState([]);
const [urls, setUrls] = useState([]);
const [percs, setPercs] = useState(0);
const uploadFile = async () => {
await Promise.all(
files.map((f, i) => {
const name = new Date().getTime() + f.name;
const storageRef = ref(
storage,
`images/products/${name}`
);
const uploadTask = uploadBytesResumable(storageRef, f);
uploadTask.on(
"state_changed",
(snapshot) => {},
(error) => {},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
setUrls((prev) => [...prev, downloadURL]);
});
}
);
})
);
console.log(urls); <-- it not works, return [], i want upload files after user click a button
};
console.log(urls); <-- it works, return [url1,url2,...]
return (
<div className="p-3"></div>
};
export default MyApp;
由于
uploadTask
的行为类似于 Promise,并在上传完成时使用其快照数据进行解析,因此以下内容应该可以解决问题(未经测试):
const uploadFile = async () => {
await Promise.all(
files.map((f, i) => {
const name = new Date().getTime() + f.name;
const storageRef = ref(
storage,
`images/products/${name}`
);
uploadBytesResumable(storageRef, f)
.then(snapshot => {
return getDownloadURL(storageRef);
})
.then((downloadURL) => {
setUrls((prev) => [...prev, downloadURL]);
});
});
);
};
另一种方法是首先获取整个 URL 数组,然后设置 URL:
const urlsArray = await Promise.all(
files.map((f, i) => {
const name = new Date().getTime() + f.name;
const storageRef = ref(
storage,
`images/products/${name}`
);
uploadBytesResumable(storageRef, f)
.then(snapshot => {
return getDownloadURL(storageRef);
});
});
);
// Then set the URLs