What is the proper way to handle FBSessionStateClosedLoginFailed with iOS FB SDK 3.1.1 - ios

When my app needs to e.g. read from a user's facebook, it checks the current state the active FBSession. For the e.g. FBSessionStateOpen, it knows it can just request the information from Facebook, whereas for FBSessionStateCreatedTokenLoaded it must call openWithCompletionHandler. What FBSession method should be called if the current state is FBSessionStateClosedLoginFailed?

That means that a login attempt failed. When this happens for me I - closeAndClearTokenInformation and alert the user that login failed and ask him if he wants to login again.

In short:
In Facebook sample
https://developers.facebook.com/docs/tutorials/ios-sdk-tutorial/
When such condition occurred, their sample code will call a loginViewController or equivalent.
This is their comments when falling into this condition.
"if the token goes invalid we want to switch right back to the login view, however we do it with a slight delay in order to account for a race between this and the login view dissappearing a moment before "
P.S. I fixed this error my solving Facebook open graph setups and study more on the Scrumptious example such as "return [FBSession.activeSession handleOpenURL:url];" and "[FBSession.activeSession handleDidBecomeActive];"
In long:
This is taken from official FB doc.
http://developers.facebook.com/docs/reference/ios/3.1/class/FBSession#FBSessionState+enum
Given this is the precondition and it has passed other enum states and not a connection error:
"FBSessionStateClosedLoginFailed
Closed session state indicating that a login attempt failed"
It didn't explicitly said the problem. It may be the cached misinformation. Personally and most carefully, I would call '- (void)closeAndClearTokenInformation;", this method would clean up every cache info and show a error message such as "invalid login, please try again" to the client/user.
Then, allow the client the options to do a clean slate login again or skip this process if possible.
HTH

Related

iOS firebase auth current user get nil when restart app

Auth.auth().signIn(withEmail:
In my case, When I first time open app and sign in firebase account like above code
then I reopen app
let user = Auth.auth().currentUser
user is not nil and then I reopen app get currentUser again user is nil that mean I did not sign in
I have the other app do like this, but the user always not nil.
I wonder why this happens.
Firebase automatically restores the authenticated user when the app restarts. But this requires a call to the servers, which may take some time. If you check Auth.auth().currentUser while the check is still in progress, you will get nil as the result.
To ensure you get the value once this initial check is done, use an auth state listener as shown in the first snippet in the documentation on getting the current user. From there:
Auth.auth().addStateDidChangeListener { auth, user in
// ...
}
Once this listener fires for the first time:
either the user variable will have a value if the user authentication state could be restored,
or it is nil if the user was not signed in last time the app ran, or the authentication state couldn't be restored (for example, because the account is disabled, or the password was changed).
I think it a big possibility you might be signed in on another device or signed in a different profile and didn't know, you might have some sync problems or security issues that did a safety measurement until you fix the security issue

What is the equivalent of iOS applicationWillTerminate in IBM MobileFirst Hybrid app?

Scenario:
I want to call the logout function if the app is terminated. I'm able to do it using native code:
- (void)applicationWillTerminate:(UIApplication *)app
{
// Run Logout function
}
Problem:
How to do it in IBM mobilefirst hybrid app?
// ************************************************
Edited
First of all, user login in to the app, if the user key in the correct user id and password, it will add the userIdentity into "loginRealm".
WL.Server.setActiveUser("loginRealm", userIdentity);
Next, user closes the apps without logout. So, when the user login for the another time, MFP server will not return any feedback since it will hit this exception:
Cannot change identity of an already logged in user in realm
'loginRealm'. The application must logout first.
Hence, I have to logout the user from MFP server by setting the "loginRealm" to null in adapter;
WL.Server.setActiveUser("loginRealm", null);
The above line of code is in the logout function defined in authentication-config.xml.
The client side device runs this line of code and it will trigger the logout function. Besides, it will reload the App upon success:
WL.Client.logout('loginRealm', {
onSuccess: WL.Client.reloadApp
});
Steps that I've tried:
1) At WlcommonInit() I added WL.Client.updateUserInfo(); and if WL.Client.isUserAuthenticated("loginRealm") return true I will logout the user from server. However, WL.Client.isUserAuthenticated("loginRealm") will always return false. This is because, it needs to take sometime around (30seconds to 2 minutes) for the flag to turn true after WL.Client.updateUserInfo();. So my login still fail and hit the same error.
2) I tried to logout the users during the user click login button. But the app will refresh and return to login page again due to reloadApp. The logout code I get from IBM mobilefirst website. So user need to click and type 2 times in order to login into the main menu.
WL.Client.logout('loginRealm', {
onSuccess: WL.Client.reloadApp
});
Am I doing it wrongly? Or are there any other methods to get WL.Client.isUserAuthenticated("loginRealm") return true instantly after WL.Client.updateUserInfo(); ? Can we remove the reload app line of code in logout function?
I don't think this is doable, because that logout function (in MFP) will require server connectivity (request and response) and if the app is by then killed, I think it's going to cause unpredictable results.
Note though that it seems to be not recommended to use that function anyway? applicationWillTerminate when is it called and when not
What you should do perhaps in order to simulate it, is to logout-on-login, so that it would appear that the app is logged out when opening it. You can extend the duration of the splash screen so that the end-user will not see that s/he is logged in (in case the session was still alive between the closing and re-opening of the app), until really logged out and then you can display the login screen again or any other required screen.

GameKit Error says player not authenticated but .authenticated property = true

I have an turn-based game using GameKit in iOS. Generally, my authentication with Game Center works. My game works and I can for periods of time send moves back and forth. However, relatively frequently but not constantly, when I try to perform an action (e.g., finding a new match) over Game Center it fails with the error:
Error Domain=GKErrorDomain Code=6 "The requested operation could not be completed because local player has not been authenticated." UserInfo={NSLocalizedDescription=The requested operation could not be completed because local player has not been authenticated.}
Yet, the GKLocalPlayer.localPlayer().authenticated = true, both immediately before getting the error and after. After getting this error, the authentication viewController does not get presented and GameKit methods that rely on authentication cease to function (they don't come back to life ). Then, if I send the app to the background and then bring it back to the foreground, the error does not return when I retry the action (without requiring new login and password entry).
According to this similar observation:
GKLocalPlayer authentication not working, but isAuthenticated returns YES (Game Center sandbox)
"1.Game Center fails to complete authentication if your device has incorrect dates. So, go ahead and check the current date.
You might have done this. I trust you - iOS Simulator >> Reset Content and Settings"
I am getting this problem on the device, not the simulator, ruling out #2. Could someone help me with #1? I may be naive here, but my iPhone and iPad have the right time and date. Is there something or somewhere else I should be checking and setting?
Then, if this is not the issue, what else could be the problem? I am running iOS9.
I've seen this too, and have an open bug with Apple. In my case, I'm testing with multiple physical devices, and only one of those devices ever encounters this. On that particular device, I'm logged into iTunes using a personal account, but logged into game center using a test account.
From what I can see, when the device is using the same login for iTunes, iCloud and game Center, there are no problems. But, when I try to mix-and-match the accounts for whatever testing I need to do, then I randomly get error 6.
There doesn't seem to be anyway to recover from this, except to have the user re-login into game center. Of course, there's no way to present the login view controller again, so the only option is for the user to leave the game, kill it off, and star up again (which re-starts the game center authentication process). I trap the error now, give the user a message saying Game Center has logged them out, and explain what they need to do about it.
But as I said, when I stopped mixing up credentials on the device, the problem went away.
BTW, on a slightly related topic, I've come to view the .authenticated property as completely unreliable. It will be TRUE in conditions where you do not actually have connection to Game Center. I opened a bug on this, too. Apple closed it saying this was working as intended by using "cached" data. Thus, it will report authenticated when it's not authenticated and give you access only to outdated match and leaderboard data which had previously been saved locally.

Forced to create a new Quickblox session every time iOS app is opened

I am using the Quickblox iOS SDK 2.0.12
I have been following the instructions on Quickblox Authentication and Authorization here.
I call QBRequest createSessionWithSuccessBlock:, and then call QBRequest signUp: inside it's completion block, and then I call QBRequest logInWithUserLogin: inside the next completion block.
According to the above link, I should now have a Quickblox User Session after doing all of this. This all works perfectly and all of the calls are successful and I can see that the user is now in the Quickblox Admin Panel.
After doing this, if I make Quickblox requests they work fine. The only weird thing is that [[QBSession currentSession] currentUser] NSLogs as (null).
Anyways, if I stop running the app on the simulator, and then run the app again 10 minutes later, I check for persisted custom data so I can see if the user has already signed up or not. When the user has signed up, then I take them into the app instead of them needing to signup or login again.
Now, if I try to make any requests to Quickblox, I get the following exception:
Terminating app due to uncaught exception 'BaseServiceException', reason: 'You have missed the authorization call.
Please insert following code inside your application
[QBRequest createSessionWithSuccessBlock:errorBlock:];
Before any other code, that uses our service, but after setup credentials. Thank you.'
I don't understand why it's saying I need to create a session when I already just created one when the user first signed up. I understand that the session expires every 2 hours, but I am testing this very quickly and I am always receiving this error.
If I NSLog [QBSession currentSession] I can see that there is currently a QBSession object, but if I try to NSLog any of it's properties like sessionDetails, sessionExpirationDate, or currentUser they all log as (null).
As I know, only if you use this method - (void)startSessionForUser:(QBUUser *)user withDetails:(QBASession *)session expirationDate:(NSDate *)sessionDate , you can use this property correct. But I didn't ever use it.
For recreating a session I use [QBConnection setAutoCreateSessionEnabled:YES] and for chat I keep QBUUser in my Manager, and after entering foreground I check XMPP connection [[QBChat instance] isLoggedIn]. Maybee it may help you.

Facebook already authorized callback issue

The second time I tried to authorize an app in Facebook it gives me back a window
You have already authorized app name. Press okay to continue.
The question is what is called back/delegate that is called after I press okay, because I somehow need a way to remove the login view controller after this
The callback is the same as when you wasn't authorized. Same process.
Back in your application you don't even have to (and even can't) make the distinction.
In your UIApplicationDelegate, be sure that the - (BOOL)application:handleOpenURL: method calls - (BOOL)handleOpenURL: on the Facebook object.

Resources