IOS user Mnagement

9 posts, 1 answers
  1. Anne Sophie
    Anne Sophie avatar
    16 posts
    Member since:
    Oct 2015

    Posted 16 Feb Link to this post

    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.

  2. Martin
    Admin
    Martin avatar
    67 posts

    Posted 18 Feb Link to this post

    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.
     
  3. Anne Sophie
    Anne Sophie avatar
    16 posts
    Member since:
    Oct 2015

    Posted 19 Feb in reply to Martin Link to this post

    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")
           }

  4. Anne Sophie
    Anne Sophie avatar
    16 posts
    Member since:
    Oct 2015

    Posted 19 Feb in reply to Anne Sophie Link to this post

    To clarify

    "Telerik token = NIL"

    gets printed from the second block

  5. Answer
    Martin
    Admin
    Martin avatar
    67 posts

    Posted 22 Feb Link to this post

    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.
     
  6. Anne Sophie
    Anne Sophie avatar
    16 posts
    Member since:
    Oct 2015

    Posted 22 Feb in reply to Martin Link to this post

    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

  7. Martin
    Admin
    Martin avatar
    67 posts

    Posted 24 Feb Link to this post

    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.
     
  8. Martin
    Admin
    Martin avatar
    67 posts

    Posted 24 Feb Link to this post

    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.
     
  9. Anne Sophie
    Anne Sophie avatar
    16 posts
    Member since:
    Oct 2015

    Posted 24 Feb in reply to Martin Link to this post

    Thanks I just realised now that when i now log out the facebook token persists preventing me from logging back in with facebook.
Back to Top