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
721 stars 325 forks source link

upload large files ( > 500MB):[javascript] 'Upload error!', [Error: NSMallocException] #291

Open sandeepkundu4344 opened 2 years ago

sandeepkundu4344 commented 2 years ago

I am uploading a file to S3 which is around 700MB, its working fine on some of the IOS devices but constantly failing on iPhone XR, Version 14.7.1

here is the configuration I have

Version: 14.7.1
React Native: 0.63.4
react-native-background-upload: 6.5.0

here is the code I am using



const options = {
      type: 'multipart',
      method: 'POST',
      headers: {
        'content-type': file.type, // server requires a content-type header
        'content-length': `${fileInfo.size}`,
      },
      url: 'https://XXXX.s3.us-east-2.amazonaws.com',
      field: 'file',
      path: file.uri,
      parameters: {
        ...S3Policy.generate({
          bucket: this.state.bucket,
          region: this.state.region,
          accessKey: this.state.accessKey,
          secretKey: this.state.secretKey,
          successActionStatus: 201,
          key: `video/${fileInfo.name}`,
          date: new Date(),
          contentType: fileInfo.mimeType,
        }),
      },
    };

Upload.startUpload(options)
      .then((uploadId) => {
        console.log('Upload started');
        this.setState({customLog: 'Upload started'});
        Upload.addListener('progress', uploadId, (data) => {
          console.log(`Progress: ${data.progress}%`);
          let value = data.progress;
          this.props.updateUploadState({
            videoInProgressPercentage: value,
            uploadId: uploadId,
          });
          console.log(
            'Progress: ' + this.props.uploadState.videoInProgressPercentage,
          );
          this.setState({customLog: 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) => {
          console.log('Completed!', uploadId, data);
        });
      })
      .catch((err) => {
        console.log('Upload error!', err);
        alert('Error: ' + err);
      });```

      it goes to catch block and throw the error 'Upload error!', [Error: NSMallocException] on iPhone xr / SE device but works on iPhone 11 Pro and iPhone 11 and simulators 
AlkanV commented 2 years ago

you are uploading a very large file using post/multipart upload. the multipart upload is done by loading data into memory. since your data is very large, you are getting a memory error. instead of this, upload your videos using put method, which is handled by file system, instead of memory. by doing this, you can fix this problem. another way can be compressing the file, but since it is very large, compressing could be also problem.

however, to use put method, a backend change is required.
we had same problem in the past (we are not using this package, but the problem is same) and we solve it using put method, instead of post/multipart. i hope this helps.

fuhrthom commented 2 years ago

@AlkanV could you tell us exactly which method you used instead and how did you call that? I tried to use the upload async of FileSystem, but it constantly fails for files which are large.

AdvMaple commented 1 year ago

I'm having the same issue, this is related to #306