How to access document attachments with Java SDK?

I couldn’t find any explanation in the manual, nor any method in the API reference to access the attachments of a JsonDocument. How can I do that?

What do you mean by attachments? I assume you are not referring to content()?

No, I mean the kind of binary file attachments you can associate with a JSON document in Couchbase Lite (http://developer.couchbase.com/mobile/develop/guides/couchbase-lite/native-api/attachment/index.html)

In fact, I’m using the Java SDK to display in a web app documents that have been created in a mobile app.

To my knowledge attachments are not stored as documents, so out of the box the SDK has no clue about them.

We are planning potential tighter mobile integration, but it’s not there yet. Maybe you can serve them in a different fashion?

You mean there are some features that are supported by Couchbase Lite and not supported by Couchbase Server? That’s something I did not expect. In this case, I could probably upload my pictures to a backend like Cloudinary and then only store URLs in my Couchbase documents, but then I would lose a crucial advantage of Couchbase: offline mode. I like the possibility to save my image locally and then let Couchbase Lite and Sync Gateway do their thing when the network comes back.

I just tried to sync a PouchDB web app with a Couchbase Sync Gateway instance and it turns out I can’t because of some open issues like https://github.com/couchbase/sync_gateway/issues/301 and https://github.com/couchbase/sync_gateway/issues/115
This is really starting to become annoying as the promise of cross platform auto-syncing DBs is fading away.

Use the Sync Gateway’s REST API to access attachments.

In fact, you should use the REST API to access all of the Gateway’s data, instead of Couchbase SDKs — the Gateway’s bucket is considered private, since it stores extra internal metadata in there (both inside document and in extra docs) and messing with that data will really confuse it. (There are a few exceptions, mostly around defining/querying views.) If you need to use Couchbase SDKs because you have an existing codebase that uses them, use the “bucket shadowing” feature to create a secondary bucket that you can access and modify.

FYI, if you have mobile-related questions, please ask them in the Mobile forum so the people who know most about mobile will see them. I didn’t know about your question until someone else pointed me to it.

To my knowledge we’ve never promised compatibility with PouchDB, so I’m not sure where the “fading” is coming from. Compatibility is hard. We have an engineer (JChris) working basically full-time on JS-based clients and PouchDB now, and the Sync Gateway team is growing fast. Please report bugs, but snarkiness isn’t productive.

I’m really really sorry if this sounded like snarkiness as it was clearly not my intention. What I meant was that I expected Couchbase and Couchbase Lite to share the same features so that I could create and consume data in exactly the same way on mobile and on the web. But the fact that client SDKs don’t allow access to a key feature such as document attachments, and the inexistence of a web equivalent of Couchbase Lite in terms of data synchronization doesn’t allow for a full cycle to be completed between web and mobile. And using PouchDB is not even an option (even though I’ve been told a couple of times that Sync Gateway’s API is “essentially” the same as CouchDB’s replication API).

But once again, I’m just amazed by your work and the work of your entire teams. I was merely pointing out my frustration in the hopes that it would underline the need to allocate more resources to the effort to complete this full cycle, and either extend the client SDKs to support all of the features of Couchbase Lite, or to develop a JS equivalent of Couchbase Lite, which seem so important in order to fullfill the commercial promise of Couchbase.

Anyway, thanks for pointing out the possibility to use the REST API, I’ll try that out.

As a matter of fact, the mobile side of my application is working perfectly. I can create data in my iOS app, consume it as well, and everything is synced perfectly without any issue. The only issue I have is with consuming this data on the web, which is why I posted this question here.

So you confirm that I need to use the SDK in order to query views, retrieving document IDs, and then use the REST API to retrieve the documents themselves?

You can access CBS views via the sync_gateway on the Admin REST API, e.g. to access the internal SG “access” view you could use:

curl -X GET "http://localhost:4985/mydb/_design/sync_gateway/_view/access"

You can create your own custom views via the REST API using design docs:

curl -X PUT http://localhost:4985/mydb/_design/foo -H "Content-Type: application/json" -d '{"views":{"bar": {"map": "function(doc) {emit(doc.key, doc.value);}"}}}'

This will create a production view “bar” in design doc “foo” for the CBS bucket “mydb”

You can query your custom view with:

curl -X GET "http://localhost:4985/mydb/_design/foo/_view/bar"

Currently view query results are not filtered by user access so must be called as an admin.

I’ve just recently heard about that possibility but my web app (from which I need to query the view) is not running on the same server as my sync gateway, and exposing the admin endpoint to the outside world looks dangerous.

You definitely shouldn’t expose the admin port to the outside world.

We have plans to expose view queries in the public API; it might end up in version 1.1 but I’m not sure (I no longer work directly on the Gateway.) The tricky part is that the query results have to be filtered to only documents the user making the query has access to.

As a workaround, can you run a process on the same server as SG that will act as a proxy for view queries? Then you can make that process require some form of authentication, maybe just basic auth over SSL. You could write a simple special-purpose proxy like that in a page of Java/Python/Ruby/whatever…

Yes, that would work too, but I’m just scared of the added complexity that would bring to the mix. Traun’s cluster is already complex as is, especially for a non-ops guy like myself, so the less pieces I add to it, the better. If we manage to make Couchbase Server itself accessible to the outside world so that I can query views through the SDK from my web server, it will be the easiest and most maintainable situation until I can do everything from the Sync Gateway API.

@sarbogast - I am working on the same issue which you have faced 2 yrs back. Can u please help me with the attachment part in web app using Java sdk?