How to sync document to local database after user is granted access to channel?


#1

I would like to know the best way to sync my local database with documents in a channel after a user is granted access. Note, the document is not being modified, so there is not change to the document. Here is my setup.

I have two documents

  1. A userChannel document that contains all the sync gateway channels the user has access to.
  2. A document that is a part of some channel

A random document is created and synced to all users who currently have access to the channel. Then later, a new user comes along and is granted access to the channel that contains this document via the userChannel document. What I have determined is that simply adding a user to a channel (granting access in the sync gateway) does not replicate all the documents within that channel down to the user. I wish it did.

So now, I would like to sync all the documents within this channel down to the new user that was just granted access to the channel. What is the best way to do this?

I have tried a one shot pull replication of the channel (and doc id) with no success. Here is the code

/******************************************************************************/
func syncDocs(doc_ids: [String])
{
    if (myUsername != "" && myPassword != "")
    {
        for id in doc_ids
        {
            logger.log(message: "Syncing doc \(id) ", event: .i)
        }
        
        let pull = db.createPullReplication(kSyncGatewayUrl)
        
        let authenticator = CBLAuthenticator.basicAuthenticator(withName: myUsername,
                                                                password: myPassword)

        pull.authenticator = authenticator
       // pull.channels = [channel_ids]
        pull.documentIDs = doc_ids
        pull.start()
    }
    else
    {
        logger.log(message: "Tried to sync docs. Username nor password is set", event: .e)
    }
}

I have tried setting just the “documentIDs” property, just the “channels” property, and both together. Nothing syncs down to the local database.

Another approach is to use the Rest API and GET the document. But then the document is returned, not synced to the local database. So I would then have to add it to the local database… By using “putProperties”?

Summary: How do I sync/pull all the documents from a channel that a user was just granted access to?

Oh, I almost forgot. To test this, I am purging the random document from my local database. Once the document is purged, I get logger errors in my code saying that the document no longer exist on the local database… which is great and expected. Now, I would like to be able to re-sync all the documents within a channel that I have access to. Which should bring back the document that was purged.

Thank you
Sean


#2

Hey Sean,

I’m trying to chase down the best practice on this, but it sounds like it might you might want to look at one of the workaround approaches outlined here:


#3

Thank you for your reply. Those are interesting work arounds. However, after reviewing them, I do not believe they will work for me. Here’s what’s going on in my project.

  1. documents are added to a channel based on a documents lat/lon user property. The lat/lon is included in the channel name. The document itself does not know who has access to it.
  2. A user of the application gets access to a channel based on the user’s gps location. As in, the user has a myChannelsDoc that, based on gps location, parses out the name of the channels the user has access to. Every time the myChannelsDoc is update, the users access to channels in the sync gateway updates.

As the user moves around, the user gains access to some channels and loses access to others. The plan is to purge all the documents in the channel the user loses access to, and pull all the documents in the channel the user gains access to.

I have the first part down. That is, when a user loses access to a channel, I purge all documents from that channel on the users device. However, I am having an issue pulling the documents that have been purged when the user is granted access again.

Any idea on how to do this?

The only solution I have came up with so far is to use the REST API and HTTP GET the document. However, the document is returned in an async call back and not synced with the local database. So, then I would have to putProperties? Or somehow recreate the exact same document. But, I image this would cause a conflict and is not scalable. Is there a way to re-create a document that was purged on the local database without having a new revision?


#4

RESOLVED: Not exactly sure what it was… But I was able to purge documents from a channel that I had access to. Verify the documents were indeed purged. Then create a pull replication which successfully brought back the documents that were purged. Here is my code that pulled the purged documents back from the channel. I might have just been missing the pull.filter line. ugh.

/******************************************************************************/
func pullDocsFrom(channels: [String])
{
    if (myUsername != "" && myPassword != "")
    {
        let pull = myDatabase.createPullReplication(kSyncGatewayUrl)
        
        let authenticator = CBLAuthenticator.basicAuthenticator(withName: myUsername,
                                                                password: myPassword)
        
        pull.authenticator = authenticator
        pull.filter = "sync_gateway/bychannel"
        pull.channels = channels
        pull.start()
    }
    else
    {
        logger.log(message: "Tried to pull docs. Username nor password is set", event: .e)
    }
}

So to answer my original question, how to sync documents to local database after the user is granted access to the channel. What I do is.

  1. I update the userChannel document I mentioned above. The one document that keeps track of all the channels the user has access to.
  2. I wait one second (maybe not necessary) for the document to sync to the server.
  3. I then call the above function. Which successfully pulls/syncs the missing documents.