New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
s3 putObject jpg uploads base64 data to s3 when ContentEncoding
is set to base64
in React Native
#1712
Comments
Having a similar yet different issue When using putObject, I don't receive back the Location property, When using upload instead, I'm getting back Location property It does not matter which size I upload, it becomes 0 Bytes. |
Yeah so after spending way too much time on this, (it hasn't been resolved) I'll share my findings.
:( my heart |
@hgonzalez94 It's quite mind bogging to me that Amazon Sounds like It better to look for other solutions. |
@hgonzalez94 Are you trying to display your image in React Native? I did a quick test using the latest version of the SDK where I uploaded a base64 image to S3, then downloaded it and displayed it in an Here's my rough example (using TypeScript but should be easy to convert to JS): /** App.js */
import React from 'react';
import { StyleSheet, Text, View, Button, Image } from 'react-native';
import {putObject} from './src/putObject';
import {getImage} from './src/getImage';
export default class App extends React.Component {
render() {
const state = this.state;
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<Text>Changes you make will automatically reload.</Text>
<Text>Shake your phone to open the developer menu.</Text>
<Button
title="Press Me"
onPress={async () => {
await putObject();
this.setState({
hasImage: true,
image: await getImage()
});
}}
/>
{state && state.hasImage && <Image
style={{width: 100, height: 200, borderColor: 'red', borderWidth: 1}}
source={{uri: state.image}}
/>}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
}); /** putObject.ts */
import * as S3 from 'aws-sdk/clients/s3';
import {image} from './image'; //base64 encoded image for testing
const s3 = new S3({
region: 'us-west-2',
credentials: {
/* From somewhere */
}
});
export async function putObject() {
const data = await s3.putObject({
Bucket: 'BUCKET',
Key: 'test-image.jpg',
ContentType: 'image/jpeg',
Body: image
}).promise();
} /** getImage.ts */
import * as S3 from 'aws-sdk/clients/s3';
const s3 = new S3({
region: 'us-west-2',
credentials: {
/* From somewhere */
}
});
export async function getImage() {
const data = await s3.getObject({
Bucket: 'BUCKET',
Key: 'test-image.jpg'
}).promise();
return 'data:image/jpg;base64,' + (data.Body as Buffer);
} |
Hey chris thanks for your reply. So by 'corrupted' (my apologies, it was a poor choice of words) I mean I'm unable to view the images on s3 from the aws side. I do upload the base 64 string fine but Ideally I would be able to upload the binary string using the sdk so I can view it from s3, or in any other medium I download. I hope you can see why I would prefer to have it in its default image representable format thats generally easy to migrate among different platforms, instead of forcing any other application of mine to adhere to this standard Im setting solely from the react native. Because of this, If I wanted to access my images, not only would I have to set up proper aws access credentials but I would also have to translate it from its base 64 string to its binary string, and thats just another step I don't want to have to take. The method you uploaded above doesn't work for me. It times out and throws an XMLHTTPRequest error saying that 'The request has already been sent' mid upload. The putObjectRequest DOES work if I provide it the base64 data string itself. What you're doing above is taking an image object which, when it gets uploaded, has its binary string representation uploaded. To anyone else interested in my work around, I chose to just post the binary string manually through a signed request I made, conforming to another web posting option aws offers. |
@hgonzalez94 I ran the same code as above, except I decoded the base64 string into a binary format before calling putObject. When I do that, the image is saved to S3 and does not need any transformations performed to view it. I have only run this test on iOS so far, and have react-native 0.47.0 installed. I've noticed differences in XMLHttpRequest behavior depending on which platform you're targeting so there may be some issue that has either been fixed, or I'm not seeing yet. To decode the base64 image, I'm using |
I'm on iOS, v 0.36.0 like I posted above. When I try submitting the binary format XMLHttpRequest gives me an error mid upload saying "The request has already been sent". I can follow that error in the source for the request but I don't know why it happens mid way. Same behavior on android |
@hgonzalez94 |
Hey @chrisradek I'll shelve this for now, but I am unable to upgrade to that version of react native at this time. I have a work around for now, but I'll have to see about upgrading at a later time. |
ContentEncoding
is set to base64
in React Native
@hgonzalez94 If you can post the workaround as a gist, that would be awesome. I know sending HTTP messages with binary payloads in earlier versions of React Native could be tricky, so I'm sure others who are unable to upgrade would love to see a stable way to do so. Please feel free to reopen if you have any questions or concerns. |
Hi Am trying to upload an image and download that and render in tag of react native. I have tried with the solution which @chrisradek have suggested. But it says S3 is not a constructor so i cant create an object and assign the configurations to it . Please advice. Also i am trying with aws amplify library and below is the code ,
I am able to upload , but when i download its not n a proper format . I have tried with base 64 as well as image uri . Its not working. can someone help in resolving this??? |
Just display the link to the image like this var imageFileName = "https://s3.us-east-2.amazonaws.com/nameOfFolder/nameOfFile.ext"; |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread. |
Whenever I attempt to download an image on s3 that I uploaded using s3.putObject, the file is corrupt. This is what I'm doing.
Is there anything I'm doing wrong from that snippet?
NOTE
I tried using a filestream to transmit the data that way too, and the same behavior occurs.
RN: 0.36.0
AWS-SDK-JS: 2.111.0
The text was updated successfully, but these errors were encountered: