realm / realm-js

Realm is a mobile database: an alternative to SQLite & key-value stores
https://realm.io
Apache License 2.0
5.8k stars 577 forks source link

Upload a binary image file to AWS S3 in Realm function #4261

Closed mednche closed 2 years ago

mednche commented 2 years ago

How frequently does the bug occur?

All the time

Description

Apologies if this is a question rather than a bug - I don't know where else to seek help.

I’m trying to implement an app similar to the O’FISH app. I followed the tutorial to the letter. My images are temporarily stored as binary data in MongoDB before being sent to S3 via a Realm trigger function.

I’ve written a realm function that uploads a file to my S3 bucket. This function works fine if the file is "hello world". However, I get Error: Unsupported body payload object when my file is a binary image queried from a MongoDB document.

How do I upload a binary image (straight out of a MongoDB document) to S3? Do I need to change the format my images are in?

Stacktrace & log output

No response

Can you reproduce the bug?

Yes, always

Reproduction Steps

Here is my realm function:

  var drawings = context.services.get("Cluster0").db("databaseName").collection("drawings");

  // get drawing document
  const query = { "_id": BSON.ObjectId("61c348229f2368fd6f2a2f95")};
  const projection = {
    "_id":1,
    "thumbnail" : 1,
  }
  drawings.findOne(query, projection)
  .then(doc => {
    const imageName = doc._id.toString()
    // THE UPLOAD TO S3 WORKS WITH LINE BELOW
    // const file = 'hello world'
    const file = doc.thumbnail
    console.log('file type', Object.prototype.toString.call(file)) // this logs: [object Binary]

    // call uploadImageToS3 function
    context.functions.execute("uploadImageToS3", imageName, file)
    .then (() => {
      console.log('Uploaded to S3');
    })
};

And here is my uploadImageToS3 function:

exports = async function(imageName, file) {

  const AWS = require('aws-sdk');

  AWS.config.update({
    accessKeyId :context.values.get("AWS_ACCESS_KEY_ID"),
    secretAccessKey : context.values.get("AWS_ACCESS_KEY_SECRET"),
    region: context.values.get("AWS_REGION")
  });

  const s3 = new AWS.S3({apiVersion: '2006-03-01'})
  const bucketName = context.values.get("AWS_BUCKET")

  return s3.upload({
        "Bucket": bucketName,
        "Key" : imageName,
        "Body": file,
        "ACL": "public-read",
        "ContentType": "image/jpeg",
        }).promise()
}

Version

JS SDK Version: 3.18.0

What SDK flavour are you using?

MongoDB Realm (i.e. Sync, auth, functions)

Are you using encryption?

No, not using encryption

Platform OS and version(s)

Realm Functions - JS SDK Version: 3.18.0

Build environment

No response

Cocoapods version

No response

kraenhansen commented 2 years ago

Thanks for reaching out @mednche. This repository is only tracking the development of the client-side SDK and not the Realm functions backend and as such I'll close this issue. I think the MongoDB community would be a great place to ask this question: https://community.mongodb.com