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
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,
Telerik
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"
)
}
To clarify
"Telerik token = NIL"
gets printed from the second block
Hi Diego,
Indeed the social login process may require more checks that the simple login and I will try to explain this better.
- 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).
- The received access token from Telerik Platform is the confirmation that the user is logged-in in you app (Telerik Platform).
- 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
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
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.
Martin
Telerik
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,
Telerik