Couchbase Lite 2.0 Database and its document not cleared on logout iOS


#1

Hi ,

I am using CBLite 2.0 in iOS 11.0 , XCode 9.4.1 , swift 4.

On Logout trying to erase couchbase lite db along with document , but its not working .

Here is the code i tried but when i check through the cblite tool it is there .

Code :

func closeDatabaseForCurrentUser() -> Bool {
    do {
        // Get handle to DB  specified path
        stopAllReplicationForCurrentUser()
        try database.close()
        try Database.delete(withName: 'testDb', inDirectory: database.path ?? "")
        return true
    }
    catch {
        return false
    }
}

}

Kindly help me to resolve this issue. Thanks in advance.


#2

What exceptions do you see ? Its possible that the close itself is throwing an exception and it isn’t even getting to the delete


#3

CouchbaseLite Code=16 “Cannot close the database. Please stop all of the replicators before closing the database.” UserInfo={NSLocalizedFailureReason=Cannot close the database. Please stop all of the replicators before closing the database., NSLocalizedDescription=Cannot close the database. Please stop all of the replicators before closing the database.}**

the code to stop the replicator is as follow :

func stopAllReplicationForCurrentUser() {
if let ltoken = listenerToken{
replicator.removeChangeListener(withToken: ltoken)
replicator.stop()
}
if let uLtoken = userListenerToken{
userReplicator.removeChangeListener(withToken: uLtoken)
userReplicator.stop()
}
}
I am calling all replicator to stop but still i am getting the same issue .


#4

Stopping replicators is asynchronous. You need to wait for the replicator to notify the listener that it’s stopped.


#5

so how should i approach , any help could lead to solve my issue.


#6

i did the same way as you implemented in Travel sample , but stil this doesn’t work ? Any help ?


#7

As Jens already mentioned in his post, please wait for the replicator to stop and you can do this by verifying for the status specified through the listener .


#8

After updating in CBlite 2.1 its not working , could you please help.


#9

Then give us information we need to be able to help. What is the code you’re using to stop the replicator? What error do you get? What’s logged?


#10
func stopAllReplicationForCurrentUser() {
    replicator.stop()
    userReplicator.stop()
    
    //STOP REPLICATOR ONE BY ONE
    if let ltoken = listenerToken{
        replicator.removeChangeListener(withToken: ltoken)
    }
    
    if let uLtoken = userListenerToken{
        userReplicator.removeChangeListener(withToken: uLtoken)
    }
    
    if let tokenNA = tokenNextArrivalQuery {
        replicator.removeChangeListener(withToken: tokenNA)
    }
    
    if let tokenIA = tokenInboundArrivalQuery {
        replicator.removeChangeListener(withToken: tokenIA)
    }
    
    if let tokenND = tokenNextDepartureQuery {
        replicator.removeChangeListener(withToken: tokenND)
    }
    
    if let tokenPD = tokenPreviousDepartureQuery {
        replicator.removeChangeListener(withToken: tokenPD)
    }
    print(replicator.status)
    print(userReplicator.status)
    listenerToken = nil
    userListenerToken = nil
    tokenNextArrivalQuery       = nil
    tokenInboundArrivalQuery    = nil
    tokenNextDepartureQuery     = nil
    tokenPreviousDepartureQuery = nil
}

this way i try to stop the replicator .


#11

As I said a month ago, up near the top of the thread:

You need to wait for the replicator to notify the listener that it’s stopped.

You’re still not doing that.

Here’s a high level sketch of what to do:

  1. Add a replicator change listener that, when the replicator stops, will unblock the wait in step 3
  2. Call Replicator.stop
  3. Wait
  4. When the replicator stops, the listener will unblock the wait

#12

well thanks for your response , but i tried it and found one java code where it says , need to wait and using timer it do the stuff but in ios its not working , got stuck in same issue , could you help us on this.


#13

It may help you.

First up all, remove all your liveQuery Listeners and then call stop replicator method.

Here is the small snippet of your replication Changelistener.

 listener_token = self.replicator?.addChangeListener({ (change) in
            if change.status.activity == .stopped{
                            NotificationCenter.default.post(name: .didCouchbaseStop, object: nil, userInfo: nil)
            }
})

Handle notification method in your ViewController and then redirect to rootViewController.
as Jens mentioned early. it is asynchronous, so you need to rotate a spinner until replication stopped.


#14

I tried this way and current status says it gets stopped but after that when i call database.delete() and database.close() , it says : CouchbaseLite Code=16 “Cannot delete the database. Please remove all of the query listeners before deleting the database.” UserInfo={NSLocalizedFailureReason=Cannot delete the database. Please remove all of the query listeners before deleting the database., NSLocalizedDescription=Cannot delete the database. Please remove all of the query listeners before deleting the database.}

could anyone help me on this ? ( cblite 2.1 version currently i am using)


#15

inside addchangelistener i got information about change.status == stopped , then only i am deleting the couchbase lite file , but it again saying the same thing


#16

The error you showed is about query listeners, not replications. Did you remove all query listeners?


#17

Yes i tried to remove it by using , _query.removeChangeListner(listnertoken1) but its not working at all


#18

Use a breakpoint or a print statement or something to verify that the listener was actually removed. That error message means you didn’t remove all query listeners.


#19

Also be sure that if you overwrite listenerToken1 with something else, that you either save the original value somewhere or remove it then. Each call to addChangeListener needs a remove call later using the token it generated.


#20

I am storing listenertoken ( document listener ) into model and whenever i don’t need , just remove it , whether frequently removing listener token does any impact ( any chance on crash ) ? ,