【问题标题】:How to use CustomRequest with antd upload function to upload images to firebase?如何使用带有 antd 上传功能的 CustomRequest 将图片上传到 Firebase?
【发布时间】:2019-11-22 17:26:15
【问题描述】:

我正在尝试使用 antd 上传组件和 pictures wall 示例将图像上传到我的 Firebase 存储。

最初我尝试使用操作属性as out lined here 得到相同的结果。然后,我尝试使用该问题的解决方案中概述的 customRequest 表单。在挣扎了一整天之后,我似乎无法让它工作。显然我不太明白发生了什么。

我的各种变化功能..

  handleCancel = () => this.setState({ previewVisible: false });

  handlePreview = async file => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj);
    }

    this.setState({
      previewImage: file.url || file.preview,
      previewVisible: true,
    });
  };

  handleChange = (info) => {
    console.log('handleChange',info);
    if (info.file.status === 'uploading') {
      console.log('setting loading to true');
      this.setState({ loading: true });
      return;
    }
    if (info.file.status === 'done') {
      console.log('setting loading to false');
      getBase64(info.file.originFileObj, imageUrl => this.setState({
        imageUrl,
        loading: false
      }));
    }
  };

我的自定义上传功能..

  customUpload = async ({ onError, onSuccess, file }) => {
    console.log("customUpload called");
    console.log(file);
    const storage = firebase.storage();
    const metadata = {
        contentType: 'image/jpeg'
    };
    const storageRef = await storage.ref();
    // const imageName = generateHashName() //a unique name for the image
    const imgFile = storageRef.child(`Property Photos/${file}.png`);
    try {
      const image = await imgFile.put(file, metadata);
      onSuccess(null, image);
    }
    catch(e) {
       onError(e);
    };
  };

我的渲染 JSX..

<Form.Item label="Photos">
  <div className="clearfix">
    <Upload
      listType="picture-card"
      fileList={fileList}
      multiple={true}
      accept="image"
      onPreview={this.handlePreview}
      onChange={this.handleChange}
      customRequest={this.customUpload}
    >
      {this.imageUrl ? <img src={this.imageUrl} alt="avatar" /> : uploadButton}
    </Upload>
    <Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
      <img alt="example" style={{ width: '100%' }} src={previewImage} />
    </Modal>
  </div>
</Form.Item>

它运行起来很有趣,但似乎有三个问题..

  1. 当我上传图片时,卡片/盒子会永远显示“上传”和动画旋转轮。它永远不会完成并显示图像缩略图。
  2. 在选择多个图像时,似乎只有第一个最终会出现在 Firebase 上。再也没有..
  3. 在选择要上载和单击确定的图像时,很长的暂停(5秒?),如应用程序挂起,然后再次单击任何内容。不知道为什么会这样。

感觉就像我只是不明白如何使用这个 customRequest 属性..

【问题讨论】:

    标签: reactjs google-cloud-firestore antd


    【解决方案1】:

    一般情况下,需要做的是:将antd Upload的“onProgress”、“onSuccess”和“onError”回调函数连接到cloudStorage上传函数对应的事件观察者上。

    https://firebase.google.com/docs/storage/web/upload-files#monitor_upload_progress

    所以,customRequest 函数可以是:

    let customRequest = ({
        file,
        onSuccess,
        onError,
        onProgress,
    }) => {
        var uploadTask = storageRef.child(`images/${file.name}`).put(file);
    
        // Register three observers:
        // 1. 'state_changed' observer, called any time the state changes
        // 2. Error observer, called on failure
        // 3. Completion observer, called on successful completion
        uploadTask.on(
            "state_changed",
            function (snapshot) {
                // Observe state change events such as progress, pause, and resume
                // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
                var progress =
                    (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
                console.log("Upload is " + progress + "% done");
    
                // CONNECT ON PROGRESS
                onProgress(progress)
    
                switch (snapshot.state) {
                    case firebase.storage.TaskState.PAUSED: // or 'paused'
                        console.log("Upload is paused");
                        break;
                    case firebase.storage.TaskState.RUNNING: // or 'running'
                        console.log("Upload is running");
                        break;
                }
            },
            function (error) {
                // Handle unsuccessful uploads
    
                // CONNECT ON ERROR
                onError(error)
            },
            function () {
                // Handle successful uploads on complete
                // For instance, get the download URL: https://firebasestorage.googleapis.com/...
                uploadTask.snapshot.ref
                    .getDownloadURL()
                    .then(function (downloadURL) {
                        console.log("File available at", downloadURL);
     
                        // CONNECT ON SUCCESS
                        onSuccess(downloadURL)  // Pass any parameter you would like
                    });
            }
        );
    };

    【讨论】:

    • 看起来我是选择一个还是多个他们上传到firebase的文件,这很好。但是 antd 没有显示缩略图,我注意到我的 handlechange 函数仅在 info.file.status 为“上传”时才被调用。当 info.file.status 完成时,它永远不会被第二次调用。似乎 antd 并没有注意到文件已成功上传的事实,即使调用了 onsuccess,正如我看到“文件可用”的 console.log 以及 downloadURL 所证明的那样。
    • 我是否应该在这里做更多的事情,以便 antd 知道文件已上传,handlechange 被调用,并且我看到 hte 上传图像的缩略图?好像我还缺少什么。
    猜你喜欢
    • 2021-07-03
    • 2023-02-08
    • 1970-01-01
    • 2021-03-19
    • 2020-03-05
    • 2020-06-24
    • 2019-08-23
    • 2018-06-14
    • 1970-01-01
    相关资源
    最近更新 更多