New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SyncUser.currentUser is not cleared on log out #6006

Open
sipersso opened this Issue Jun 8, 2018 · 8 comments

Comments

Projects
None yet
5 participants
@sipersso
Copy link

sipersso commented Jun 8, 2018

Logging out doesn't seem to clear the current user. This makes it very hard to switch users. I had to manually remove the signed out user from the SyncManager user store to get sign out/switch user to work as expected. Are you supposed to have to do this manually? In the realm tasks app, the current user is ignored when switching users, which seems like a workaround too.

I am using full synchronziation for my realm if that helps

Code Sample

SyncManager.addAuthenticationListener(object:AuthenticationListener{
    override fun loggedOut(user: SyncUser?) {
        SyncManager.removeAuthenticationListener(this)
        user?.let {
              //Without this line SyncUser.currentUser() will not return null even though the user has bee 
              // signed out
            SyncManager.getUserStore().remove(user.identity, user.authenticationUrl.toString())
        }
        signOutFromMyOwnAuthSystemAndRestartApp()
    }
    override fun loggedIn(user: SyncUser?) {}
})
SyncUser.current().logOut()

Version of Realm and tooling

Realm version(s): 5.2.0

Realm sync feature enabled: yes

Android Studio version: 3.1.3

Which Android version and device: Nexus 5x

@nhachicha

This comment has been minimized.

Copy link
Contributor

nhachicha commented Jun 9, 2018

@sipersso by design when you log out, the user is not removed immediately but instead tagged to be removed on the next app startup. However SyncUser.current() should return null when you log out.

I'm wondering why you need the user to be cleared immediately after a logout? if that's a requirement of your app then you can use your approach with remove

@sipersso

This comment has been minimized.

Copy link

sipersso commented Jun 9, 2018

I don’t need the user to be cleared. I just need SyncUser.currentUser() to return null and it doesn’t unless I clear it from the user store. Is this really by design? If so, how am I supposed to see if there is a signed in user or not?

When logging out, i sign the user out, then starts the activity for initialization. The init activity checks SyncUser.current(). If a user exists it uses that to create a sync configuration, if not, it shows the sign in screen.

@nhachicha

This comment has been minimized.

Copy link
Contributor

nhachicha commented Jun 9, 2018

I just need SyncUser.currentUser() to return null and it doesn’t unless I clear it from the user store

This shouldn't be the case SyncUser.currentUser() should return null if the user was logged out (marked as inactive). It will be interesting to see if you can reproduce this scenario, then inspect this line to see why user.isValid() is returning true.

@cmelchior

This comment has been minimized.

Copy link
Contributor

cmelchior commented Jun 10, 2018

We have unit tests for both logging out explicitly: https://github.com/realm/realm-java/blob/master/realm/realm-library/src/androidTestObjectServer/java/io/realm/SyncUserTests.java#L220 and if the user expires https://github.com/realm/realm-java/blob/master/realm/realm-library/src/androidTestObjectServer/java/io/realm/SyncUserTests.java#L174

So if you find that this doesn't work for you, it would be great if you can reproduce in a sample project.

@sipersso

This comment has been minimized.

Copy link

sipersso commented Jun 15, 2018

Definitely not working here, which is weird because SyncManager.getUserStore().remove is one of the first lines executed in the log out in the SyncUser.logOut() method.

Pretty short on time now and with the workaround in place (manually clear the userStore), log out works, so it might a few weeks until I can set up a sample project.

@sipersso

This comment has been minimized.

Copy link

sipersso commented Jun 15, 2018

To add to this. If I call SyncUser.current() straight after SyncUser.logOut() it does return null. However, when called in the next activity it doesn't. I guess SyncUser.logOut() clears the sync user from a cache, while it remains on disk? And then the next SyncUser.current() reads from disk?

@cmelchior

This comment has been minimized.

Copy link
Contributor

cmelchior commented Jun 15, 2018

Hmm, interesting. Thank you for that information. Our unit test just reads SyncUser.current() right after calling .logout(). This gives me something more to go after

@sipersso

This comment has been minimized.

Copy link

sipersso commented Jun 15, 2018

Sorry for all the edits, I deleted the comment by mistake and have pasted it back now.

Ok, I think I have identified the issue. When logging out you can't have any open realms or else SyncUser.current won't be cleared when starting another activity. This is a big issue, since the local realm files gets corrupted if you use them with the wrong sync configuration.

Making sure that no realm instances are open is easier said than done because of the activity lifecycle in android. To get this working, I had to put the same workaround in place that I used when handling ClientResetErrors #5944.

I added the following code and now sign out works as expected, but the workaround is very ugly to say the least

private fun signOutFromObjectServer() { 
    if (Realm.getGlobalInstanceCount(Realm.getDefaultConfiguration()) > 0) {
            val handler = Handler()
            handler.postDelayed(Runnable {
                signOutFromObjectServer()
            }, 500)
            return
    }
    SyncUser.current().logOut()
    //Sign out from custom auth system and restart app    
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment