Efficient way to read+write data from CouchDB - couchdb

I am implementing an application that includes a user who logs in to access a document stored in a hosted CouchDB store. The user provides their credentials to the app, and once the app authenticates them, the app then has two jobs:
Get the Document ID associated with that user's data
Update the "lastOpened" value stored in that document
I am having to do those two things in a way that seems rather inefficient: I read a View which maps the app's user identifier (their email address in this case) to their Document ID. Once I have the Document ID (and have added it to the session for later use) I then have to request the Document, uptick the "lastOpened" value, then save the Document back to the store.
That looks like 3 trips to the database to me: 1. Get the Document ID from the View, 2. Get the Document, using that ID, 3. Save the updated Document.
Is there anyway to reduce that work to fewer database trips?

If you can change the document structure, you could use the user's login name as the document ID. That way, you don't have to use a view. Using update handlers, you could even do all the work in one request.

That looks like 3 trips to the database to me: 1. Get the Document ID from the View, 2. Get the Document, using that ID, 3. Save the updated Document.
Is there anyway to reduce that work to fewer database trips?
You can fetch document from a view by adding "?include_docs=true" query parameter in request. So two steps instead of three.

Related

Locking documents in firestore or don't allow two users edit a document at the same time

stack: NodeJS, ExpressJS, Firebase DB, VueJs
Question:
How to lock a firebase doc? I want to not allow two users editing a same document on front-end.
Example: Like in front-end if a user fetches a document by some id ant starts editing, editing takes like 10 minutes because there are a lot of inputs, but then a second user comes and tries to edit the same document by id. How to prevent it?
My solution: Create a database collection storing the id of currently edited document. And whenever a user tries to edit an document, there should be a check if the id doesnt exist in the collection and on save button the id should be removed from the collection.
Is my solution is good?
Maybe there are other solutions...
There is no pessimistic locking built into Firestore, but I'd typically implement this by adding a field to the document that is being locked. Something like currentEditor with as its value the UID of the current editor.
To manipulate this field you'll want to use a transaction to prevent users from overwriting each other's data, and you'll then want to use server-side security rules to enforce this.

Getting a list of BuildFire plugin users from the Widget side

I am developing a plugin that allows the user the post content that I am storing in an object in publicData. To identify the user that posted the data, I am storing the _id that is returned from buildfire.auth.getCurrentUser() in that publicData object along with the content of the post.
Is there a way I can access a list of the users of my plugin, then iterate through that to find the user with the corresponding _id? A list of the users of my plugin must exist somewhere, I just do not know how to/if I can access it.
Any help on this would be greatly appreciated!
I would recommend caching the user object's nonsensitive data. Remember, you have a bit more access to the logged-in user over fetching another user profile using the user id. https://github.com/BuildFire/sdk/wiki/How-to-use-Auth#buildfireauth-getuserprofileoptionscallback
Since the user profile picture URL is really an API, you don't have to worry about the user changing it since it will always return the latest. The other property I recommend you cache is the Display name (not the first name and last name) since that rarely changes as well. This way your performance wont suffer and you can do a lazy fetch for a distinct list of user ids an update them as needed. KNowing most wont need an UI updates since nothing changed

couchdb validate against documents in an other database

I need to write an design doc that checks whether or not an ID exists on a product in an other database (same CouchDB instance) before allowing the addition of a document to the database.
This should go along the lines of the following:
Actor -> Requests to store a document in the database.
System -> Checks if a document exists in an other database so it can validate the input from the request.
System -> Adds the document if validation succeeds or refuses the document if validation fails.
My question is. Is it possible to validate against the content of an other database? I have not been able to find anything about accessing the documents in an other database from within a design document (update handler) so far.

Update object info for old post

I am sending user id(stored in our own DB) as actor while posting activity on getstream. In object field I am sending other info of user such as name/dob etc. which are in our database too.
Suppose some one updates the user info e.g. name in our application, the object will still have old information in the post. How can this scenario be handled in best possible way?
All activities stored in Getstream are normalized, thus there is no way for you to update usernames stored within activities. Best practice is to not store data directly in the Getstream activity but store a reference to the data inside your own database (as you are doing right now for the actor field).
{
"actor": "user:$USER_ID"
"object": "post:$POST_ID"
}
Where $USER_ID is the id of the user in you local database and $POST_ID is the id of the post (this can be any sort of data e.g. comment, post, like) in your local database). You are also allowed to store extra (custom) fields on the Getstream API.
When you use one of Getstream's integration packages you get this functionality for free. You could have a look at these packages to see how they handle this.

Purging documents in Couchbase Lite

I have a mobile app using Couchbase lite. When the user logouts, I want to remove some of the documents on the device; the user-specific documents. I do not want to remove all of the documents. Documents have a purgeDocument() method that I thought I could call on those user-specific documents.
The problem is that the purged documents are not re-synced down to the device if the user logs back in and a pull replication is run.
Based on the little I know of CouchDB sync protocol, it makes sense that those are not re-synced down because there are not newer Sequence updates on those user-specific documents to trigger a re-sync.
How should I approach this problem?
Possibilities
Delete the whole database (including common documents) and lose performance.
Somehow reset the last sequence for the replicator and hope the replicator does not transfer the already-downloaded docs over the wire. (Probably would screw up CBL)
Have separate databases, one that stores the user-specific docs and one that contains common docs. Databases can have filtered replicators (by channel) so it would be feasible to partition the incoming data into separate databases. The problem would be the seamless reference loading between documents of differing databases when using CBLModel objects wrappers.
As i understand from the official documentation in the subsection Purging documents, you are not retrieving the document again just because it has not been modified/updated (in short, its rev is the same) on the server side.
You can try to create again a dummy document with the same type and, for example, username (or whatever you are using to identify the user's configuration) when the user logs again in your app so that you trigger the pull replication from the server. You probably will have a conflict that can easily be solved taking the revision from the server.
I hope this idea helps a little.
UPDATE AFTER COMMENT
The idea is to store somewhere the id and type of the user's documents you're going to purge. That way you can create a new dummy document with those two fields when the user logs in again. Perhaps this new dummy document triggers the pull replication.
NOTE: I haven't tried this method. I am just guessing what it might be a work around to your problem.
I would suggest that your backend modifies the selected documents - this could be just a timestamp update - upon user login, which will post the new revisions to the device
You can keep purging the documents when the user logs in.
To solve problem of re-syncing specific document, I think the easiest way is to use filtered replication where the filter is document id.
These document IDs can be created in a manner which can be derived. For example it can be as UserDocument::.
Now when the user logs in you can start one shot replication with document ID as filter. This can only be done in one shot. And when this One Shot finishes you can start replication again by changing the setting of the replication(changing filter/channel).
following is the URL by Couchbase which explains filtered replication by document ID.
https://developer.couchbase.com/documentation/mobile/1.4/guides/couchbase-lite/native-api/replication/index.html#filtering-by-document-ids
Try Push after Purging the document with Couchbase Lite which allows you to Pull the document from the server at a later point.

Resources