rn-fetch-blob
rn-fetch-blob copied to clipboard
Upload formData with S3 pre-signed URL
Hello, first, here is the versions I'm using :
"react": "16.9.0",
"react-native": "0.61.5",
"rn-fetch-blob": "^0.12.0"
I'm trying to upload a file using S3 and pre signed URL. I'm using rn-fetch-blob like this :
RNFetchBlob.fetch('POST', url, {
'Content-Type' : 'multipart/form-data',
}, [
{
name : name,
filename: file.fileName,
data: formData(fields)}
]).then((resp) => {
console.log(resp);
}).catch((err) => {
// ...
console.log("Catch error", err);
})
where formData is basically a function returning a FormData() object containing all needed informations for S3 key, region, bucket, ....and the urlis the pre signed URL for S3 upload. However, by doing this, I'm getting a black screen, so I just wanted to know, if S3 upload (with pre signed method) was possible to achieve using rn-fetch-blob?
Any ideas, help, is very welcome. Thanks !
Try application/octet-stream for your content-type header. What are you seeing in terms of errors? What are the contents of the actual file that was uploaded in S3?
@MayoudP Hi, did you upload to s3 with the pre signed method finally? any code will be appreciated :) Thanks! @justinmchase
{
"rn-fetch-blob": 0.12.0,
"react-native": 0.61.5
}
@matamicen This code works for both Android & iOS
const presignedUrl = "https://xxx.s3.amazonaws.com/abc.mp4?AWSAccessKeyId=xxx&Expires=xxx&Signature=xxx&x-amz-acl=public-read&x-amz-security-token=xxx";
const response = await RNFetchBlob.fetch(
'PUT',
presignedUrl,
{
'Content-Type': undefined
},
RNFetchBlob.wrap(file.path.replace('file://', '')),
)
Note
1. { 'Content-Type': undefined } is needed for iOS (works with Android)
2. file.path.replace('file://', '') is also needed for iOS (works with Android)
RNFetchBlob.fetch(
'PUT',
link,
{
'Content-Type': undefined
},
RNFetchBlob.wrap(Platform.OS === "android" ? this.selectedImage.uri : this.selectedImage.uri.replace("file://", "")),
)
.then((resp) => {
console.log("Response data", resp)
this.onImageUploadSuccess(resp)
}).catch((err) => {
this.onUploadFailure(err)
})
**Above code worked for me**
Hi @manilbajracharya @siriwatknp This is how I've implemented it:
s3.getSignedUrl('putObject', {
Key: 'responses/' + filename,
Body: file,
Bucket: AWScreds.bucketLanding,
Tagging: "tag"
}, (err, url) => {
if (url) {
console.log("SIGNED URL", url);
// ========================Upload file========================
RNFetchBlob.fetch('PUT', url,
{
'Content-Type': undefined
},
RNFetchBlob.wrap(filePath))
.then((res) => {
console.log("Uploaded", res.text())
})
.catch((err) => {
console.log("Err", err);
});
// ========================Upload file========================
}
This throws no error in the console, but when I paste the signed url in the browser, this is what I see:
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
RN version: 0.63.4 OS: Android Library version: ^0.12.0
Could you please let me know where I might be making a mistake? Thank you.
RNFetchBlob.fetch( 'PUT', link, { 'Content-Type': undefined }, RNFetchBlob.wrap(Platform.OS === "android" ? this.selectedImage.uri : this.selectedImage.uri.replace("file://", "")), ) .then((resp) => { console.log("Response data", resp) this.onImageUploadSuccess(resp) }).catch((err) => { this.onUploadFailure(err) })**Above code worked for me**
Thanks a lot this works you can also set filetype in content type it will work.