Vydia / react-native-background-upload

Upload files in your React Native app even while it's backgrounded. Supports Android and iOS, including camera roll assets.
MIT License
720 stars 325 forks source link

Uploading Videos to S3 uploads immediately, but does not upload correclty #310

Open onsiteUDA opened 1 year ago

onsiteUDA commented 1 year ago

Updated to v6.5.1 Videos from camera roll on IOS were being uploaded to S3 instantly, the file seemed to be there in the bucket, however previewing/downloading the file uploaded would not play as if it had been corrupted. Photos work fine they show up as intended

        const access = new Credentials({
            accessKeyId: myKeyID,
            secretAccessKey: mySecretAccessKey
          });

          const s3 = new S3({
            credentials: access,
            region: 'us-west-2',
            signatureVersion: 'v4',
          });

          const s3Params = {
            Bucket:myBucket,
            Key: image.s3key,
            Expires: 900,
            ContentType: mimeType,
            ACL: 'public-read',
          };

          let url = s3.getSignedUrl('putObject', s3Params);
          options = {
            type: 'raw',
            method: 'PUT',
            headers: {
              'content-length': image.size.toString(),
              accept: mimeType,
            },
            url: url, 
            field: 'file',
            path:  path,
            // Below are options only supported on Android
            notification: {
              enabled: true,
              onCompleteTitle: 'File uploaded successfully',
              onErrorTitle: 'File failed to upload',
            },
          };

Upload.startUpload(options).then((uploadId) => {
  console.log('Upload started')
  Upload.addListener('progress', uploadId, (data) => {
    console.log(`Progress: ${data.progress}%`)
  })
  Upload.addListener('error', uploadId, (data) => {
    console.log(`Error: ${data.error}%`)
  })
  Upload.addListener('cancelled', uploadId, (data) => {
    console.log(`Cancelled!`)
  })
  Upload.addListener('completed', uploadId, (data) => {
    // data includes responseCode: number and responseBody: Object
    console.log('Completed!')
  })
}).catch((err) => {
  console.log('Upload error!', err)
})

Attempted to use Post instead using the following

 options = {
            type: 'multipart',
            method: 'POST',
            headers: {
              'content-type': mimeType, 
              'content-length': image.size.toString(),
            },
            url: myURLPost,
            field: 'file',
            path: path,
            parameters: {
              ...S3Policy.generate({
                bucket: myBucket,
                region: 'us-west-2',
                accessKey: myKey
                secretKey: mySecrectAccessKey,
                successActionStatus: 201,
                key: image.s3key,
                date: new Date(),
                contentType: mimeType,
              }),
            },
            // Below are options only supported on Android
            notification: {
              enabled: true,
              onCompleteTitle: 'File uploaded successfully',
              onErrorTitle: 'File failed to upload',
            },
          };

It also had the same outcome.

I then proceeded to downgrade back to where I was (6.2.0) since it was working then. The first method used works for photos as intended but not for the videos; however, the second method used, correctly uploads the video to S3 as they are in the bucket and can be previewed/downloaded correclty

He1nr1chK commented 1 year ago

Hi @onsiteUDA,

Don't know if I am too late, and I also don't know if this might solve your problem but I encountered something similar. In my case files with whitespace in the file name would show that it was finished uploading but on S3 showed 0kb. I used react-native-document-picker & expo-file-system. My solution was to do the following:

const { extension } = await Upload.getFileInfo(filePath);
  localPath = `${FileSystem.documentDirectory}${nameWithNoWhitespace}.${extension}`;
  await FileSystem.copyAsync({
    from: filePath,
    to: localPath,
});

Hope this helps someone!