Backendless Support
 
Solved

Logout & login does not reissue user token (User Service API, iOS Swift)

This is a repeat post that was initially filed as a Question when I meant to Report A Problem.

When the app is first launched and initialized and the user logs in, there is no issue retrieving data. I can confirm a successful user login with a call to currentUser which returns the logged in user, and can verify the user token is not nil.

I have a logout button that makes a call to backendless.user.logout() (and have also tried the async method), and then performs an unwind segue that returns to the login view controller. I can confirm the user has been successfully logged out with another call to currentUser which returns nil and checking the user token which also returns nil.

When trying to log in again, the user is successfully logged in as confirmed by another call to currentUser which returns the logged in user, however the user token still returns nil. This results in data not being returned from my query. This problem can only be resolved by quitting the app completely, at which point the login works and a new user token is issued and data is retrieved successfully. However, using the logout feature reintroduces the problem. I have also disabled persistent login, and disabled multiple logins from the admin console.

Any help is appreciated.

Leave a Comment

Comments (17)

photo
1

Hello Adam.

What version of iOS-SDK do you use?

I've just checked and everything works fine for me. User token changes every time I'm trying to login/logout (v 4.0.21)

Here is my code:

  1. // login
  2. backendless.userService.setStayLoggedIn(true)
  3. backendless.userService.login("a@a.com", password: "111", response: { loggedInUser in
  4. print ("User logged in. Current user token is: \(self.backendless.userService.currentUser?.getToken() ?? "USER TOKEN IS NIL")")
  5. }, error: { fault in
  6. print ("Error: \(String(describing: fault?.detail))")
  7. })

  1. // logout
  2. backendless.userService.logout({ loggedOut in
  3. print ("User logged out. Current user token is: \(self.backendless.userService.currentUser?.getToken() ?? "USER TOKEN IS NIL")")
  4. }, error: { fault in
  5. print ("Error: \(String(describing: fault?.detail))")
  6. })

Screenshot with the result attached.

Regards, Olga

photo
1

See the attached image. I have used your code exactly.

photo
1

I have added a logout button to the login screen and now the user token is updated with each login. It seems the issue must be with the unwindSegue. I will investigate further.

photo
1

Apparently the user-token is overwritten with nil somehow when you do the unwindSegue. I'd advice you to check whether you manipulate on the user-token anywhere in your code, or whether any SDK method manipulating on user-token is triggered on the second login call. You can check out our iOS-SDK code from GitHub for debugging purposes.

photo
1

I can reproduce the issue with the following simple setup:

  1. Initial view controller contains just a button, which upon tap calls the login function (using hard coded login for testing, though also can take input field text). Login function performs segue upon successful login
  2. Destination view controller is a tableView embedded in a navigation controller (Initial --> Nav Controller --> Table View Controller)
  3. Bar button item, upon tap calls logout function and calls self.dismiss.
  4. Logout is successful, tableview controller dismisses and now back to initial view controller
  5. Subsequent attempts to login again using same button result in NIL user token and therefore no data retrieved

Strangely, if the login and logout buttons are both placed in the initial view controller, then I can login and logout multiple times without issue.

photo
photo
1

Cannot reproduce.

Please check the screenshots.

  1. @IBAction func pressedLogin(_ sender: Any) {
  2. backendless.userService.setStayLoggedIn(true)
  3. backendless.userService.login("a@a.com", password: "111", response: { loggedInUser in
  4. print ("User logged in. Current user token is: \(self.backendless.userService.currentUser?.getToken() ?? "USER TOKEN IS NIL")")
  5. }, error: { fault in
  6. print ("Error: \(String(describing: fault?.detail))")
  7. })
  8. }

  1. @IBAction func pressedLogout(_ sender: Any) {
  2. Backendless.sharedInstance().userService.logout({ loggedOut in
  3. print ("User logged out. Current user token is: \(Backendless.sharedInstance().userService.currentUser?.getToken() ?? "USER TOKEN IS NIL")")
  4. self.dismiss(animated: true, completion: { })
  5. }, error: { fault in
  6. print ("Error: \(String(describing: fault?.detail))")
  7. })
  8. }

Regards, Olga

photo
1

I believe my issue must be arising somewhere in my file renaming process, as I named the app one name on the console and attempted to rename the app on my local machine. I redownloaded the app template and did not attempt to rename anything and I am having no issues. Thank you!

photo
1

Update: I have narrowed the issue down to one line in my TableViewController.

In the table view controller's viewDidLoad, I call:

  1. let dataStore = backendless.data.of(GroupObject().ofClass())

This singular line causes the logout/login issue. Screenshots attached.

The storyboard setup is the same.

photo
1

Can you prepare a minimal sample to reproduce the problem?

photo
1

Sure - should I scrub my API key and App ID, or leave it in? And what about user login?

photo
1

Please leave them in so that the test would be as close to original as possible. You can create a test user for us so that we could try logging him in.

photo
1

See attached.

photo
photo
1

Hello Adam,

I've checked your project and that is wrong:

1. You don't have the GroupObject table in your application, but you're trying to create dataStore for it.

2. I assume UserObject is class to represent the Users table. Please don't replace the system tables and classes and use the BackendlessUser class instead.

Regards, Olga

photo
1

Hi Olga,

  1. Are you saying that I don't have the GroupObject table in my backend? There is definitely a GroupObject table (albeit with only one object). Please let me know if my implementation of dataStore is incorrect on the client side - I was following the documentation but I may be misunderstanding.
  2. I will implement the UserObject using the BackendlessUser class to see if that has any effect.

It seems I can retrieve the data on the initial login from the GroupObject table in my backend, but cannot logout and then login again and retrieve the information again. I did not implement the mapping of the data to the TableView as I was providing a minimum viable product for reproducing the error.

I still do not understand why an incorrect implementation of the dataStore for a table query would result in the inability to log back in properly - shouldn't the request simply return with a fault and have no effect on the login process?

photo
photo
1

Hello,

sorry you really have the GroupObject table.

We'll investigate this issue and answer you as soon as possible.

Regards, Olga

photo
1

Issue has been fixed in the version 4.0.22 of iOS-SDK. Please update and verify whether it works fine.

Regards, Olga

photo
1

Error has been resolved - thank you!

photo