/** * I recently needed to upload a file from the phone's filesystem to S3 using temporary credentials * (i.e. access key, secret key and session token) issued by an API for a React Native application, * without the overhead of Base64 encoding the file and passing it over the bridge (as it could be * several MB big), and wanted to avoid writing native code to do this. * * None of the S3 libraries online worked with the temporary credentials, but I figured out a * solution using the official AWS SDK (which is good, as it supports all the relevant authentication * out of the box) and the react-native-fetch-blob module, which allows you to upload directly from the * filesystem with the correct Content-type header (as far as I can tell, React Native's fetch only * allows multipart/form-data, which was causing the pre-signed URL signature check to fail). * * Below is a skeleton version, which requires the aws-sdk and react-native-fetch-blob npm modules. */ import AWS from 'aws-sdk/dist/aws-sdk-react-native'; import RNFetchBlob from 'react-native-fetch-blob' const uploadFile = async (localPath, contentType, region, accessKeyId, secretAccessKey, sessionToken, bucket, key) => { try { // Configure the AWS SDK with the credentials AWS.config.update({ region, accessKeyId, secretAccessKey, sessionToken, }); // Create a new instance of the S3 API const s3 = new AWS.S3(); const s3Url = await s3.getSignedUrl('putObject', { Bucket: bucket, Key: key, ContentType: contentType, }); const result = await RNFetchBlob.fetch('PUT', s3Url, { 'Content-Type': contentType }, RNFetchBlob.wrap(localPath)); } catch (e) { console.error('Error', e); } }