This is a migrated thread and some comments may be shown as answers.

IOS user Mnagement

8 Answers 67 Views
Apple iOS SDK
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Kevin
Top achievements
Rank 1
Kevin asked on 16 Feb 2016, 11:54 AM

I thouht i had the user login correctly handled but it now appears i did not i am calling loginWithFacebook and this logs the user in or registers them on the app. however when i try to access the EVuser later in the app i am getting nil values. In the documentation it says 

Often you may want to extend the user session, keeping the user logged in to the application until they choose to log out or the access token expires. The SDK handles this for you behind the scenes. When a user logs in successfully to your app, the data about the current user and the access token of the user are saved in the NSUserDefaults storage. Thus they are persisted between app start-ups and the token is reused until the user logs out. 

 What keys should i be looking for?

 

code to check user login later in app

EVUser.fetchWithAccessToken(currentUserAccessToken, block: { (loggedInUser:EVUser!, error:NSError!) -> Void in
    if (error == nil) {
        print("The user " + loggedInUser.username + " is logged in with valid access token.")
    } else {
        print("The user is not logged in: " + error.domain)
    }
})

Returns The user is not logged in: Invalid request. (presumably because the currentUserAccessToken is nil)

when i call EVuser.logout() i return to the loginViewController where the following gets called

if (FBSDKAccessToken.currentAccessToken() != nil)
{
    print("User is already logged in")
    self.loginSuccess()
    // User is already logged in, do work such as go to next view controller.
}

 

so the fb token persists and the user is returned to the main app

 

I can post more code from loginViewController if required. i think my sequence of events might be slightly off.

8 Answers, 1 is accepted

Sort by
0
Martin
Telerik team
answered on 18 Feb 2016, 12:23 PM

Hi Diego,

When using the Social Login there are two authentication tokens involved:

  • one from the Social Authentication Provider
  • one from Telerik Platform

You can examine the whole social login procedure for more information.

In regard to your inquiry.

Using FBSDKAccessToken.currentAccessToken() returns the current token issued from Facebook. This means that the user is logged in the Facebook app, but this does not mean that the user is logged-in in your app (Telerik Platform). In order to check the current logged-in user you may use EVUser.CurrentUser(). So the code will look like the following.

Note how the access token of the current user is retrieved before calling fetchWithAccessToken:

var currentUser:EVUser = EVUser.currentUser();
var currentUserAccessToken:String = currentUser.accessToken
 
EVUser.fetchWithAccessToken(currentUserAccessToken, block: { (loggedInUser:EVUser!, error:NSError!) -> Void in
    if (error == nil) {
        print("The user " + loggedInUser.username + " is logged in with valid access token.")
    } else {
        print("The user is not logged in: " + error.domain)
    }
})

Here the currentUserAccessToken is the one issued from Telerik Platform and not from the Social Authentication provider. This way you can check that the user is logged in your app or not.

Hope this helped.

Regards,

Martin
Telerik
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Kevin
Top achievements
Rank 1
answered on 19 Feb 2016, 10:49 AM

Unfortunately this does not help my understanding, particularly on steps 3-5 on the diagram on the social login documentation.

bellow is my facebook login code

override func viewDidLoad() {
    super.viewDidLoad()
    if (FBSDKAccessToken.currentAccessToken() != nil)
    {
        print("User is already logged in With FaceBook")
        //self.loginSuccess()
        // User is already logged in, do work such as go to next view controller.
    }
    else
    {
        let loginView : FBSDKLoginButton = FBSDKLoginButton()
        self.view.addSubview(loginView)
        loginView.center = self.view.center
        loginView.readPermissions = ["public_profile", "email"]
        loginView.delegate = self
    }
         
}
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
    print("Returned from Login")
    if ((error) != nil)
    {   
       print(error.description)
       // Process error
     }
        else if result.isCancelled {
            print("cancelled")
            // Handle cancellations
        }
        else {
            // If you ask for multiple permissions at once, you
            // should check if specific permissions missing
            if result.grantedPermissions.contains("email")
            {
                print(result.token)
                 
                // Do work
            }
            //print(result.token.tokenString)
            print(FBSDKAccessToken.currentAccessToken().tokenString)
             
            self.fbToken = result.token
 
            registerUserFromFacebook()
             
            let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let viewController = mainStoryboard.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
            UIApplication.sharedApplication().keyWindow?.rootViewController = viewController
 
        }
    }
     
    func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
        print("User Logged Out")
    }
     
    func registerUserFromFacebook(){
         
        //print(fbToken.tokenString)
        EVUser.loginWithFacebook(fbToken.tokenString , block: { (user:EVUser!, error:NSError!) -> Void in
            if (error == nil) {
                //if accesstoken !set in preferances
                 
 
            } else {
                print("Failed to log in the user: " + error.domain)
            }
        })
 
    }

 

the code you posted id the same as mine.

          let TelerikUser = EVUser.currentUser()
       currentUserAccessToken = TelerikUser.accessToken
        
       if (currentUserAccessToken != nil){
           EVUser.fetchWithAccessToken(currentUserAccessToken, block: { (loggedInUser:EVUser!, error:NSError!) -> Void in
               if (error == nil) {
                   print("The user " + loggedInUser.username + " is logged in with valid access token.")
               } else {
                   print("The user is not logged in: " + error.domain)
               }
           })
       }else{
           print ("Telerik token = NIL")
       }

0
Kevin
Top achievements
Rank 1
answered on 19 Feb 2016, 10:51 AM

To clarify

"Telerik token = NIL"

gets printed from the second block

0
Accepted
Martin
Telerik team
answered on 22 Feb 2016, 11:29 AM

Hi Diego,

Indeed the social login process may require more checks that the simple login and I will try to explain this better.

  1. When you get an access token from Facebook you pass it to Telerik Platform in order to login to the backend service of you app (the access token from Facebook substitutes the username and password that are used in regular login).

  2. The received access token from Telerik Platform is the confirmation that the user is logged-in in you app (Telerik Platform).

  3. I see from your login screen code that you are checking whether there is a Facebook access token present to validate weather the user is logged-in. The existence of such does not mean that the user is logged-in in your app (based on point 2). For example, if you are logging out the user and the user is navigated to this view, it would be expected that there is no access token for the current user. I suggest you modify the code in viewDidLoad() with the following changes (see the comments):

override func viewDidLoad() {
    super.viewDidLoad()
    if (FBSDKAccessToken.currentAccessToken() != nil)
    {
        print("User is already logged in With FaceBook")
         
                             / /  Get the current user from EV
        var currentUser:EVUser = EVUser.currentUser();
        var currentUserAccessToken:String = currentUser.accessToken
          
         // 1. Check if currentUserAccessToken == nil and if true -> call registerUserFromFacebook();
          
         // 2. If currentUserAccessToken != nil there is access token, so check if it is valid with the following snippet:
        EVUser.fetchWithAccessToken(currentUserAccessToken, block: { (loggedInUser:EVUser!, error:NSError!) -> Void in
            if (error == nil) {
                print("The user " + loggedInUser.username + " is logged in with valid access token.")
            } else {
                print("The user is not logged in: " + error.domain) // logout the user and allow the user to login with FB
                registerUserFromFacebook();
            }
})
    }
    else
    {
        let loginView : FBSDKLoginButton = FBSDKLoginButton()
        self.view.addSubview(loginView)
        loginView.center = self.view.center
        loginView.readPermissions = ["public_profile", "email"]
        loginView.delegate = self
    }   
}


Let me know if this works for you.

Regards,

Martin
Telerik
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Kevin
Top achievements
Rank 1
answered on 22 Feb 2016, 04:46 PM

So do you have to call EVUser.fetchWithAccessToken to get user id and user name as

var currentUser:EVUser = EVUser.currentUser()
print(currentUser.username)

still returnes nil

0
Martin
Telerik team
answered on 24 Feb 2016, 11:15 AM

Hi Diego,

At the moment the stored information that can be retrieved when calling  (in case there is logged in user) EVUser.currentUser() is the accessToken, displayName and email. So you should use EVUser.fetchWithAccessToken() to retrieve the username.

In any case it is preferable to use EVUser.fetchWithAccessToken() before every critical operation, as calling EVUser.currentUser() will return infrormation for the stored user on the device but still this does guarantee you that this user is still logged in as stated here.

Moreover with EVUser.fetchWithAccessToken() you can retrieve some custom properties stored in the User content type (for instance upon user registration one may want to store information about the user's age and gender in the User content type).

Also, it will be convenient and we will consider storing the username as well in the currentUser property after login.

Let me know if this has helped.

Regards,
Martin
Telerik
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Martin
Telerik team
answered on 24 Feb 2016, 11:56 AM

Hi Diego,

Let me correct one important typing mistake.

The sentence:
In any case it is preferable to use EVUser.fetchWithAccessToken() before every critical operation, as calling EVUser.currentUser() will return information for the stored user on the device but still this does guarantee you that this user is still logged in as stated here.

should be:
In any case it is preferable to use EVUser.fetchWithAccessToken() before every critical operation, as calling EVUser.currentUser() will return information for the stored user on the device but still this does NOT guarantee you that this user is still logged in as stated here

Regards,

Martin
Telerik
 
Everlive is now Telerik Backend Services, and is part of the Telerik Platform.
 
0
Kevin
Top achievements
Rank 1
answered on 24 Feb 2016, 05:09 PM
Thanks I just realised now that when i now log out the facebook token persists preventing me from logging back in with facebook.
Tags
Apple iOS SDK
Asked by
Kevin
Top achievements
Rank 1
Answers by
Martin
Telerik team
Kevin
Top achievements
Rank 1
Share this question
or