mongodb / stitch-js-sdk

MongoDB Stitch JavaScript SDK
Apache License 2.0
113 stars 67 forks source link

Issue with S3 upload image without Stitch function #290

Open wgarrido opened 5 years ago

wgarrido commented 5 years ago

Hi,

I try to upload an image to my S3 bucket with AwsServiceClient.factory but I have an issue.

This is my part of code

aws = this.state.client.getServiceClient(AwsServiceClient.factory, "s3")

const args = {
  ACL: "public-read",
  Bucket: "XXX",
  ContentType: this.state.avatarSource.type,
  Key: this.state.avatarSource.fileName + '.jpeg',
  Body: BSON.Binary.fromBase64(this.state.avatarSource.data, 0)
};

const request = new AwsRequest.Builder()
  .withService("s3")
  .withAction("PutObject")
  .withRegion("eu-west-3")
  .withArgs(args);

aws.execute(request.build())
  .then(result => {
    console.log(result)
  }).catch(err => {
    console.log(err)
  });

I import BSON in the top with

import {BSON} from 'mongodb-stitch-react-native-sdk'

But the function BSON.Binary.fromBase64() doesn't exist.

I try to put blob file in Body arguments and my application return an error the body must be type of io.ReadSeeker because you use the "AWS SDK for Go"

It is possible to transform Base64 to io.ReadSeeker in javascript ?

Do you have anothers solutions without use Stitch function ?

Thank you

wgarrido commented 5 years ago

We found solution by getting content image and return an arraybuffer with Axios then we convert this with BSON.Binary function

Axios.get(this.state.avatarSource.uri, {responseType:'arraybuffer'})
            .then(response => {
              console.log(response)
              const args = {
                ACL: "public-read",
                Bucket: "XXX",
                ContentType: this.state.avatarSource.type,
                Key: this.state.avatarSource.fileName+'.jpeg',
                Body: new BSON.Binary(new Uint8Array(response.data), 0),
              };

              const request = new AwsRequest.Builder()
                .withService("s3")
                .withAction("PutObject")
                .withRegion("eu-west-3")
                .withArgs(args);

              aws.execute(request.build())
                .then(result => {
                  console.log(result)
                }).catch(err => {
                  console.log(err)
                });
            })

Thank's @fabioavelino to solves this issue with me.

efleurine commented 5 years ago

Hi everyone,

I am able to ulpload an image and retrieve it. But I am wondering how do I delete a file when the user changes it. Can I do that with the Put action too?

thanks.

@wgarrido @fabioavelino

thanks in advance for your help.

wgarrido commented 5 years ago

Hi @efleurine

I guess you can use the DeleteObject action of the same way as PutObject . https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#S3.DeleteObject You find argument to pass here : https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#DeleteObjectInput

matt2legit commented 4 years ago

If anyone is trying to read and upload a local file using RNFetchBlob, here's what worked for me:

const fileBase64 = await RNFetchBlob.fs.readFile(file, 'base64');
const fileBuffer = new Buffer(fileBase64, 'base64');

const request = new AwsRequest.Builder()
      .withService('s3')
      .withAction('PutObject')
      .withRegion('us-east-1')
      .withArgs({
        ACL: 'public-read',
        Bucket: bucket,
        ContentType: 'image/jpeg',
        Key: key,
        Body: new BSON.Binary(new Uint8Array(fileBuffer), 0),
      });

const result = await aws.execute(request.build());

Thanks to @wgarrido for sharing the answer above which had the clues to figure this out.