S3 Presigned URL with React Native

Maybe this piece of code may help some people having troubles uploading on S3 Presigned URL with React Native.

My S3PresignedUrl uploader component (it uses flowtype):

/**
*
* @flow
*/
'use strict';
class S3PresignedUrl {
sendFile(presignedurl: string,
file: {uri: string, type: string, name: string},
onSuccess: () => void,
onFail: () => void,
onProgress: () => void) {
    // from http://blog.rudikovac.com/react-native-upload-any-file-to-s3-with-a-presigned-url/
const xhr = new XMLHttpRequest();
    xhr.upload.addEventListener('progress', (e) => {
// handle notifications about upload progress: e.loaded / e.total
console.log('progress');
console.log(e);
onProgress(e);
}, false);
    xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// Successfully uploaded the file.
console.log('successfully uploaded presignedurl');
console.log(xhr);
onSuccess(file.uri);
} else {
// The file could not be uploaded.
console.log('failed to upload presignedurl');
console.log(xhr);
onFail(file.uri);
}
}
};
xhr.open('PUT', presignedurl);
xhr.setRequestHeader('X-Amz-ACL', 'public-read');
// for text file: text/plain, for binary file: application/octet-stream
xhr.setRequestHeader('Content-Type', file.type);
xhr.send(file);
}
}
export { S3PresignedUrl };

Here is my nodejs script to generate my presignedurl (it includes a schemeurl creation that you can ignore at the end). At this time, this is probably one of the most useful part of this blog post (the rest can be found on Google) as the content type for audio and video are the correct one for iOS — without these exact content types, S3 failed with an error message not very explicit:

var aws = require('aws-sdk');
aws.config.region = 'us-west-2';
const s3 = new aws.S3();
const filename = 'video.mov'; // whatever you want to be saved in your S3 bucket.
const type = 'video'; //video or audio (for poodll recorder schemeurl)
const contenttype = 'video/quicktime';
//const contenttype = 'application/octet-stream'; // audio content type
const timelimit = 100;
const s3Params = {
Bucket: 'elasticbeanstalk-us-west-2-01326',
Key: filename,
ContentType: contenttype,
Expires: 600000,
ACL: 'public-read'
};
var signedurl = s3.getSignedUrl('putObject', s3Params);
console.log(signedurl);
// Here is the schemeurl url link for the Poodll Recorder.
console.log('poodllrecorder://?timelimit='+timelimit+'&type='+type+'&presignedurl='+encodeURIComponent(signedurl));

Note: you also need to tweak your S3 bucket permission to allow PUT see https://devcenter.heroku.com/articles/s3-upload-node#initial-setup

Big thanks to: