首页 > 解决方案 > 将多个图像上传到 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>

标签: javascriptreactjsfirebase-storagees6-promise

解决方案


您可以遍历所有选择的文件并在承诺中上传每个文件,然后等待所有承诺解决,如下所示:

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} />
  ))
}

注意:我没有测试上面的代码,所以如果有什么问题,请随时评论,我会更新它。


推荐阅读