Save image attachment

Hi,

I’m trying to save a jpg image as an attachment. I’m not sure sure what format I need to convert the image data to. Is it?

  1. base64
  2. image binary
  3. blob

Here’s my sample code:

fetch(dbUrl() + '/user/profileImage.jpg?rev=' + userProfileObject._rev, { method: 'put', headers: { 'Accept': 'application/json', 'Content-Type': 'image/jpg' }, body: blob });

I’m getting a 400 error, “bad attachment”.

1 Like

What would be the difference between 2 and 3 in your question? To give an answer, you send the binary data as is (no base 64 or any other encoding).

I don’t know the difference. I’m planning to use https://www.npmjs.com/package/blob-util to convert the base64 string to blob.

What do you think?

I don’t know enough about your program or the library in question to make a comment.

But the “put” request should accept any blob in the message body right?

Yes, the documentation (for Sync Gateway, at least) is here.

If you’re updating an attachment via a PUT to the attachment’s URL, the HTTP body is literally the exact attachment data. So in your case it would be raw JPEG image data.

So it turns out that attachments needs to be in binary string form. I used blob-util:

blobUtil.base64StringToBlob(byteString, mimeString) .then(function(blob) { return blobUtil.blobToBinaryString(blob); }) .then(function(binaryString) { return fetch(dbUrl() + '/test/test.jpg?rev=' + test._rev, { method: 'put', headers: { 'Accept': 'application/json', 'Content-Type': mimeString }, body: binaryString }); })

Hope this helps others in this situation.

Huh. I guess that’s something JavaScript-specific? I didn’t think it was that difficult to work with binary data in JavaScript…

What value for mimeString do you use?

It doesn’t really matter. CBL stores the content_type of attachments, but doesn’t use it itself.

Ok, but in n this example its passed to the blobUtil.base64StringToBlob function also.

I’m using react-native and blobUtil doesn’t seem to work. If I had an example of what the body should look like I’m sure I can figure out a solution, but I can’t find an example.

@nick-couchbase,

The following chart should help you with specifying the mime-type value, MIME Types - The Complete List.

Thanks. Unfortunately the code above doesn’t seem to work in react-native. Do you have an example of what the binaryString looks like? I’m trying to reverse engineer what these libraries do to see if I can come up with an alternative.

It should be raw binary data. I guess in JS you have to represent that as a string object? It would look like garbage if you inspected it.

I’ve given up trying to do it in javascript. It was beginning to feel solving it in react-native was going to take long than the universe has left to live :frowning:

Is there a java example of posting a binary attachment to the sync-gateway? Or any example it it working in any other language?

curl -X PUT http://host/db/doc/attachment.jpg --header Content-Type:image/jpeg --data-binary @/path/to/attachment.jpg

Would it be possible to add a new endpoint to the rest api? I want to be able to send a file using a standard js library, but they all seem to use a multipart form data http body, rather than just a stream of bytes.

Multipart is optional for the single-document APIs. You can send the doc as JSON by using ContentType: application/json, and you can request responses in JSON using Accept: application/json (in fact I think that’s the default?)

I showed a very simple example above of uploading an attachment by itself.