1

I am currently uploading videos and images using base64 encoding but it was highly recommended to use an alternative to this. I am using RNFetchBlob to read the encoded file and then attach it to SuperAgent for uploading. I have seen some examples of using FormData to attach the file but cannot find a complete working example. If someone could provide a code example on how to achieve this I would greatly appreciate it.

RNFetchBlob.fs.readFile(filePath, 'base64')
      .then((base64data) => {
          let base64Image = `data:video/mp4;base64,${base64data}`;

          let uploadRequest = superagent.post(uploadURL)
          uploadRequest.attach('file',base64Image)

          Object.keys(params).forEach((key) => {
            uploadRequest.field(key,params[key])
          })

          uploadRequest.on('progress', function(e) {
              this.props.setVideoUploadProgress(e.percent)
           }.bind(this))

      uploadRequest.end((err,resp) => {

      })
})
Amila Dulanjana
  • 1,884
  • 1
  • 16
  • 33
Victor Altadonna
  • 193
  • 2
  • 10
  • Is it a necessity that you want to use base64 encoding ?. I could show you other alternative of uploading video and Image to cloud and appending the video url and Image url to database. This is just a suggestion. If you want my alternative do comment ! – Ron Astle Lobo Nov 27 '18 at 06:13
  • I would prefer to avoid base64 encoding completely, but I am just not sure how to accomplish that. I have read that it is not recommended to use a byte array for uploading when using react native so I am just not sure what my alternatives are. Thanks. – Victor Altadonna Nov 28 '18 at 05:08

2 Answers2

0

I am using react-native-image-picker to allow users to select or record a video, which gives me a URI of the video file path. Then I use RNFetchBlob to upload it to the server.

    RNFetchBlob.fetch('POST', 'Upload API endpoint', {
        ...this.getHeader(),
        'Content-Type': 'multipart/form-data'
        // Change BASE64 encoded data to a file path with prefix `RNFetchBlob-file://`.
        // Or simply wrap the file path with RNFetchBlob.wrap().
    }, [
            // element with property `filename` will be transformed into `file` in form data

            { name: 'file', filename: 'video.mp4', data: RNFetchBlob.wrap(this.state.videoUri) },
            // custom content type
        ]).uploadProgress({ interval: 250 }, (written, total) => {
            let uploaded = (written / total) * 100
            this.setState({
                uploadProgress: uploaded.toFixed(1)
            })
        })
        .then((response) => {
            if (response.ok) {
                this.setState({
                    uploading: false,
                    uploadSuccess: true,
                    uploadFailed: false,
                })
            }
        }).catch((err) => {
            this.setState({
                uploading: false,
                uploadSuccess: false,
                uploadFailed: true,
            })
        })
John
  • 8,846
  • 8
  • 50
  • 85
  • Thanks for the reply. I just tested this out and it is the exact same file size as the base64 encoded upload, which doesn't make sense to me because I thought that base64 encoding increases the file size up to 33%. Also, for some reason the uploadProgress isn't working correctly for me. – Victor Altadonna Nov 28 '18 at 05:06
  • @John is there any other way to upload video files other than formdata or RNFetchBlob? Our server doesnt support this and expects binary file. – Sankar Jun 30 '20 at 20:22
  • You can use RNFetchBlob to upload binary files as well. as the name itself says BLOB – John Jul 01 '20 at 13:05
0

Basically you have to give the path of your image, audio or video to fetch blob. The following code worked for me:

RNFetchBlob.fetch(
  'POST',
  `${BASE_URL}vehicle/vehicleRegistration`,
  {
    Authorization: 'Bearer ' + authToken,
    'Content-Type': 'multipart/form-data,octet-stream',
  },
  [
    {
      name: 'photo',
      filename: 'vid.mp4',
      data: RNFetchBlob.wrap(vehicleImage.uri),
    },
    {
      name: 'email',
      data: user.email,
    },
    {
      name: 'userId',
      data: user.id,
    },
    {
      name: 'vehicleType',
      data: values.vehicleType,
    },
    {
      name: 'make',
      data: values.make,
    },
    {
      name: 'buildYear',
      data: values.buildYear,
    },
    {
      name: 'model',
      data: values.model,
    },
    {
      name: 'nickName',
      data: values.nickName,
    },
    {
      name: 'engineSize',
      data: values.engineSize,
    },
  ],
)
  .uploadProgress((written, total) => {
    console.log('uploaded', written / total);
  })
  .then(response => response.json())
  .then(RetrivedData => {
    console.log('---retrieved data------', RetrivedData);
    Toast.show({
      text1: 'Success',
      text2: 'Vehicle Added to Garage!',
      type: 'success',
    });
  })
  .catch(err => {
    console.log('----Error in adding a comment----', err);
    Toast.show({
      text1: 'Request Failed',
      text2: err?.response?.data?.message,
      type: 'error',
    });
  });