-
Notifications
You must be signed in to change notification settings - Fork 53
Images in Example project as Couchbase Lite attachments #11
Comments
@jamiltz it seems that you are right, it works to use the attachment as a uri like so
that's great! But when I looked at the device database it hadn't replicated the attachment from sync_gateway so that's why it's not showing up. Let me double check and restart sync and try again |
👍 Ok let me know if the replication works |
Nevermind, it's there. Still not working though so it's something else. |
What is there? And what is not working just to be clear on what I should run. |
so on my forwarded port i can see this |
Ah ok that's a pity. Can you push the code on a branch on your fork? |
definitely, I'll try and do that soon. but I did a curl to get the img up so it will be hard for you to replicate my exact sync_gateway. You'll have to curl an attachment in yourself. |
yeah, so it's just one line and to curl in an image something like this (but you'll have to add a document with id of 100)
|
Thanks that's great I'll have a look tomorrow. |
I've done a little testing
So perhaps CouchbaseLite is adding a https-like security layer? Can the response headers for couchbase lite be modified? CouchDB is specifying content type. Perhaps that is needed. |
@jamiltz almost certain this is a CORS issue on the lite server. Can you advise how to allow * |
@ssomnoremac sorry for the lack of response. Could be! What makes you think CORS? I've was biten so many times by it ;) Have you checked the request headers with httpscoop or charles? |
@jamiltz I couldn't figure out how to sniff the http request between my app and the the cbLite server using Charles. I'm not too familiar with Maven but, assuming this is CORS, making this kind of modification would require forking the couchbase maven repo or pulling the entire cb code into the app, correct? |
@jamiltz, @ssomnoremac So the issue and reason we think it's a CORS issue is firstly as you mentioned this has bitten us before :) We had basically the exact same problem when developing our Angular app on CouchDB. From the browser in chrome we are able to get access to the attachment using the same URI as in the react native app. Now the reason CORS exists is to control exactly what we are trying to do - take an asset from service x and re serve it. Looking at line 60 of the LiteServlet I see the only header being added is www-auth, ideally we would add origin here to remove our expected problem. The perfect way would be to pass all the headers we want similarly to how credentials is done! I have played around with this a bit and cannot seem to find any other reason other than CORS. Changing our code to request the URI from our couchDB AWS hosted server presents the image perfectly. |
I finally got down to reproducing the issue and it turns out to be the Image component stripping out the credentials from the url to which CBL Listener returns a 401 Unauthorized. So I see two possible workarounds:
N.B: I recommend using Charles for network debugging the CBL REST API on a device or emulator. Start Charles then from the Android WiFi page, select the current network and add a manual proxy in advanced settings (set the hostname to the IP of your computer and port to 8888 - the default reverse proxy port on Charles). Return to the app and Charles should pick up the traffic going to the CBL Listener. |
Hey thanks, Yeah was going to try base64 today anyway to see if that works and I can confirm it does - I think we will use this as a work around! Thanks @jamiltz |
Does anyone have a working example of how to PUT and image attachment to CBL using the rest API? |
@npomfret did you try the workaround to base 64 encode the attachment? (see @SolmyrBhaal's implementation for reference https://github.com/InfiniteLibrary/infinite-reader/pull/16/files) |
Thanks for the reply. I'm not quite sure what I'm seeing there. Is his workaround to just attach the raw base64 data instead of binary encoding it. Basically just like attaching a text file? I've not tried that but I'm sure it would work. I wanted to shrink the attachment size down though. I understand base64 encoding of images is quite bloated. There is a way to do it but I can't get the libraries to work in RN |
Yes you can add attachments by encoding them in base64 in the body. You can check the documentation or the code in comments above. Ideally, we could just pass a url to the Image component but as explained above, React Native strips out the auth header (need to check if it's still the case with React Native 0.23). In any case, I think we should update the ReactNativeCouchbaseLiteExample app to use the attachments for the movie thumbnails. |
No update in RN 0.23 regarding this issue. Adding images via the PUT |
@jamiltz we are using Android. There are two problems:
|
I think I've got something working that doesn't do the base64 attachment upload. I've had to use a package called react-native-fileupload which I understand will upload the binary data rather than the bloated base64 data. My work so far is on this fork. The problem I've got at the moment is my getAttachment function returns a Blob. Not sure how to turn that into an image or even a file on disk yet. |
Does this plugin have support for the path variable to be another URL or On Sunday, April 24, 2016, Nick Pomfret notifications@github.com wrote:
Kind Regards, Louis C. Ruch |
Not tried a remote url yet. I'm just currently stuck on getting it back out of the BCL database |
I'm not at my machine to test, but it should work fine as a blob, if the Have you tried forwarding port 5984 and accessing cblite from your machine 'adb forward tcp:5984 tcp:5984' Then from your machine just access the cblite database via browser http://127.0.0.1:5984/dbname/docname/attachment That way you can at least download and test the attachment and see if On Sunday, April 24, 2016, Nick Pomfret notifications@github.com wrote:
Kind Regards, Louis C. Ruch |
I may have spoken to soon. The upload is being accepted, but I think its not expecting a multipart form data type body, rather a stream of bytes. So the data that gets saved into CBL contains a load of http related text as well as the binary data. Need to find a way to post an http body with raw binary data in it. |
Ok, I've finally got the PUT with binary data working. I've to write some native code to stream the binary data across into CBL. The java code, is a work in progress but it does work. The base64 workaround is still needed to view the file, but that's fine. It was the increased network overhead I was worried about. And this implementation will take a file path or a URL as the source, so the source binary data doesn't need to be one the device. I've never written any IOS code so this really needs another set of eyes. |
Has anyone managed to get a document with its attachments in android? My response is missing the crucial data part:
|
The bug of the stripped auth text in the url is android only. I've raised an issue but I can't find the problem, so can't fix it... yet. However, the binary upload works in both IOS and Android now. And the attachment URL works nicely in IOS. |
Re |
Ok, thanks. So an android we're a bit stuck because we can't get attachments out either way. If we can get the Facebook Fresco project updated so that Android can load images with auth in the urls the same way as IOS I think we're good. I'll tidy up the binary upload stuff a bit in my fork and submit it. I could really do with some help with the Objective C stuff. Especially around error handling and waiting for the upload to complete. |
I've written a bit of native code to deal with upload binary attachments. Not added instructions to the docs yet but it would be good if someone else could try it out New function is called saveAttachment, and to load the data use getAttachmentUri to generate a url. As discussed - the urls don't work for images in android yet. |
Thanks! I'll give this a go. I'm curious why we need the saveAttachment method, isn't the PUT /dbname/docid/attachmentname endpoint suited for that? To be honest, I've only tried to add attachment using Postman and the nodejs request module. But I imagine that it should be possible with FormData/XmlHttpRequest/fetch. |
Hi James. Yes, its not obvious, (or I've got something very wrong!). What I found was that CBL would accept a From posted / multipart form data upload, but when I read it back the content wasn't what I expected. Both XmlHttpRequest and fetch will send a multipart form post with the file in it. When I looked in to the code I saw that CBL is expecting the body to contain only binary data. CBL doesn't parse out the multipart form data stuff (the boundary info and blank lines), and so what gets saved to disk is your binary data + some unwanted http stuff. Which obviously come back out again when you query it. I couldn't find another way to send binary data across using java script so... The native method I've added here, which still need a little work but seems to do the job, just streams the contents of a url into CBL with no additional http stuff like what you get with a multipart form post. The source of the url doesn't even need to be a file on your phone. I've tested on both devices. IOS work fine. But in Android, although the upload looks fine, as we've discussed there's an issue with RN where it doesn't add the auth headers in android so you get a 401 response when trying to download the attachment. I've tried unsuccessfully to get this fixed. Not sure what to do about it now. Maybe add (temporarily) another native method to take an attachment and just put it on disk somewhere. Until the issue is fixed properly. Does any of that make sense? |
I've made some updates to my PR, now #43 So it handles IOS asset type URIs (of the sort you get back from the camera roll. If anyone has had a chance to try it out please let me know - it would be good to get merged. |
Thanks! What do you mean about "Will your work offer a solution to core RN?" |
Doesn't your solution (Java Code) solve the problem posed by the thread I referenced: "Does fetch with blob() marshal data across the bridge". Are you not now marshaling the binary data across the bridge? |
No, all the native code does (both IOS and android) is take a uri and stream the binary data from it to another uri as the body of a PUT or POST. |
@npomfret It looks like java-core just got |
Ok, i'll try and get it merged today. |
I'm going to close this ticket as I believe the new release copes with binary attachments of any sort. |
Looks like the Android OkHttp library that react-native uses on Android doesn't support urls containing basic auth parameters and so images coming from the CBL database won't be displayed. There was talk of them fixing it in OkHttp. As of the latest RN 0.27 (which I believe got a new version of OkHttp) it is still not working. |
For anyone having problems with attachments in react-native-couchbase-lite I would like to suggest to try a new React Native module for Couchbase Lite react-native-cbl. It implements all the methods via native code calls providing better performance and richer feature set. |
Test that images can be inserted as attachments and replicated accordingly. /cc @ssomnoremac
The text was updated successfully, but these errors were encountered: