javascript - 将多个图像上传到 Firebase 存储,然后将下载 URL 调用到 Firebase 数据库
问题描述
我正在尝试同时将多个图像上传到 firebase 存储,然后将它们调用到 firebase 数据库中。我可以使用单个图像,但我不确定如何修改我的代码以允许多个图像。当我选择要上传的多张图片时,它们成功上传到 Firebase 存储,但是,只有上传的第一张图片会被分配给 featuresImage 数组并因此显示。任何帮助将非常感激。
这是我的代码:
class OtherEdit extends Component {
constructor(props) {
super(props);
this.state={
id: '',
info: {
title: '',
subtitle: ''
},
article: {
featuredImage: []
}
}
}
...
uploadImageCallBack = (e) => {
return new Promise(async(resolve, reject) => {
const file = e.target.files[0]
const fileName = uuidv4()
storageRef.ref().child("OtherMedia/" + fileName).put(file)
.then( async snapshot => {
const downloadURL = await storageRef.ref().child("OtherMedia/" +fileName).getDownloadURL()
resolve({
success: true,
data: {link: downloadURL},
})
})
})
}
...
<FormGroup className='edit-featured-image'> Featured images
<Input type="file" multiple accept='image/*' className="image-uploader"
onChange={async (e) => {
const uploadState = await this.uploadImageCallBack(e)
if(uploadState.success) {
await this.setState({
hasFeaturedImage: true,
article: {
...this.state.article,
featuredImage: uploadState.data.link
}
})
}
}}>
</Input>
<div className='image'>
{
this.state.hasFeaturedImage ?
<img src={this.state.article.featuredImage} /> : ''
}</div>
</FormGroup>
解决方案
您可以遍历所有选择的文件并在承诺中上传每个文件,然后等待所有承诺解决,如下所示:
const uploadImageCallBack = async (e) => {
const uploads = [];
const promises = [];
e.target.files.forEach(file => {
const path = storageRef.ref().child(`OtherMedia/${uuidv4()}`);
const uploadPromise = path.put(file).then(async snapshot => {
/** @TODO it's a good idea to do some error handling here */
const downloadURL = await path.getDownloadURL();
uploads.push({
success: true,
data: { link: downloadURL },
});
});
promises.push(uploadPromise);
});
await Promise.all(promises); // Wait for all promises to complete
return uploads;
};
现在您可以从Input
's更新您的状态onChange
:
<Input type="file" multiple accept='image/*' className="image-uploader"
onChange={async (e) => {
const uploads = await this.uploadImageCallBack(e);
const featuredImages = uploads.filter(upload => upload.success).map(upload => upload.data.link);
await this.setState({
hasFeaturedImage: true,
article: {
...this.state.article,
featuredImages // I took the liberty to rename this to plural, as this is an array
}
});
}}>
</Input>
您可能想放弃您的hasFeaturedImage
状态,因为您可以像这样简单地显示所有图像(如果数组为空,则不会显示任何图像)。
{
this.state.article.featuredImages.map((imageSrc, index) => (
<img key={`image-${index}`} src={imageSrc} />
))
}
注意:我没有测试上面的代码,所以如果有什么问题,请随时评论,我会更新它。
推荐阅读
- recaptcha - Google reCaptcha v3 挑战?
- android - 在 Android Studio 上更改特定布局
- javascript - 使用我拥有的代码单击时,如何使我的图像消失?
- ruby-on-rails - 使用 Pagy 分页按分数排序?
- javascript - 这段代码中的括号是做什么用的?
- python - 在 Pandas 中规范化 Json 文件
- ssl - Helm Ingress 中的 Traefik LetsEncrypt 证书
- java - 使用构建器创建火花会话时出现 NoSuchFieldException
- high-availability - 每个节点上有两个网络接口的 Pacemaker 集群
- python - Python 将日期作为参数