User not logged in error in Facebook SDK iOS - iphone

How can I fix this error in my program? Using Facebook SDK.
Error Domain=facebookErrDomain Code=10000 "The operation couldn’t be completed. (facebookErrDomain error 10000.)" UserInfo=0x5da9b10 {error=<CFBasicHash 0x5db09a0 [0x1087400]>{type = mutable dict, count = 2,
entries =>
2 : <CFString 0x5db7920 [0x1087400]>{contents = "type"} = <CFString 0x5d35420 [0x1087400]>{contents = "OAuthException"}
3 : <CFString 0x5d34970 [0x1087400]>{contents = "message"} = <CFString 0x5da96b0 [0x1087400]>{contents = "Error validating access token: The session is invalid because the user logged out."}
}
}

I think the solution enbr posted is not complete. I will explain why:
Access token errors are returned when the Facebook session expires and you continue using an old access token. Logout is not the only scenario in which sessions expire (e.g. change login password in the web). Hence, it is not enough to simply clean the user defaults after logout.
From the client side, we don't know if the access token we have is actually valid, until a response comes with such information. Therefore, you need to detect access token errors and restore the Facebook instance to a working state by cleaning the old access token and expiration date. This way, the user will need to login again to obtain a new access token.
So, IMO, what you need to do is:
Handle errors and detect when an access token error has occurred.
When an access token error occurs, logout automatically and clean user defaults to remove old access token (step 3).
As a result of logout, you need to clean user defaults for access token and expiration date (as enbr posted).
Here you have some code that can be used to detect access token errors:
-(BOOL)isAccessTokenError:(NSError *) error {
if ([[error domain] isEqualToString:#"facebookErrDomain"] && [error code] == 10000 ) {
NSDictionary *userInfo = [error userInfo];
NSDictionary *errorAsDictionary = [userInfo objectForKey:#"error"];
if ([[errorAsDictionary objectForKey:#"type"] isEqualToString:#"OAuthException"]) {
//Invalid access token
return YES;
}
}
if ([[error domain] isEqualToString:#"facebookErrDomain"] && ([error code] == 110 || [error code] == 190)) {
//Error accessing access token
return YES;
}
return NO;
}
The places to handle such errors are:
- (void)request:(FBRequest*)request didFailWithError:(NSError*)error;
- (void)dialog:(FBDialog*)dialog didFailWithError:(NSError *)error;
I hope this helps.
UPDATE:
I forgot to mention. If you are using the SSO feature (most likely), I think it is a very good idea to clean the facebook cookies before login. Sometimes, after an invalid access token error, it seems login won't bring back the Facebook object to a working state (valid access token) unless a "clean login" is performed. Not always work though.
Also, If you are not using the SSO feature, this used to fix the ghost login popup that appeared to automatically disappear again.
This is how I clean the cookies:
NSHTTPCookieStorage* cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray* facebookCookies = [cookies cookiesForURL:
[NSURL URLWithString:#"http://login.facebook.com"]];
for (NSHTTPCookie* cookie in facebookCookies) {
[cookies deleteCookie:cookie];
}
enter code here

I just recently came across this error also. Here is the solution. Place this code in your main FBSessionDelegate (probably your app delegate).
- (void)fbDidLogout {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:#"FBAccessTokenKey"];
[defaults removeObjectForKey:#"FBExpirationDateKey"];
[defaults synchronize];
}
Then delete and reinstall the app!

Related

iOS Authorize.net integration issue

I am developing iOS app, in which I have integrated authorize.net payment gateways using auth.net iOS API.
I followed each and every steps which are mentioned in their doc. Now each time, when a transaction request is sent to auth.net server on live environment it gives me error (Code E00007) i.e. "User authentication failed due to invalid authentication values".
I checked Login ID and Transaction Key and those are correct.
Even I tried with Auth.net support person, but still it did not work out.
The test enviroment and request were successful. But on Live env. it gives me the problem
My code follows:
For device registration:
Here I have put XXXX.... instead of real transaction key and login id.
MobileDeviceRegistrationRequest *mobileDeviceRegistrationRequest =
[MobileDeviceRegistrationRequest mobileDeviceRegistrationRequest];
mobileDeviceRegistrationRequest.mobileDevice.mobileDeviceId =
[[[UIDevice currentDevice] uniqueIdentifier]
stringByReplacingOccurrencesOfString:#"-" withString:#"_"];
mobileDeviceRegistrationRequest.mobileDevice.mobileDescription = #"iPhone";
mobileDeviceRegistrationRequest.anetApiRequest.merchantAuthentication.name = #"XXXXXXXXX";
mobileDeviceRegistrationRequest.anetApiRequest.merchantAuthentication.password = #"XXXXXXXXXXXXXX";
[AuthNet authNetWithEnvironment:ENV_LIVE];
AuthNet *an = [AuthNet getInstance];
[an mobileDeviceRegistrationRequest:mobileDeviceRegistrationRequest];
After that the code for payment request:
MobileDeviceLoginRequest *mobileDeviceLoginRequest = [MobileDeviceLoginRequest mobileDeviceLoginRequest];
mobileDeviceLoginRequest.anetApiRequest.merchantAuthentication.name = #"XXXXX";
mobileDeviceLoginRequest.anetApiRequest.merchantAuthentication.password = #"XXXXXX";
mobileDeviceLoginRequest.anetApiRequest.merchantAuthentication.mobileDeviceId =
[[[UIDevice currentDevice] uniqueIdentifier] stringByReplacingOccurrencesOfString:#"-" withString:#"_"];
// Set up an AuthNet instance.
[AuthNet authNetWithEnvironment:ENV_LIVE];
AuthNet *an = [AuthNet getInstance];
[an setDelegate:self];
// Process a mobile device login request.
[an mobileDeviceLoginRequest:mobileDeviceLoginRequest];
But in the initial registering request I am receiving the failure with error code E00007. Any settings I missed?
please provide the transaction key
mobileDeviceLoginRequest.anetApiRequest.merchantAuthentication.transactionKey = #"XXXXXX";
it works for me

OAuth refresh token error

I'm using OAuth 2.0 to sign into a website. so each time when i try to log into the server i got a response that refer to an expiration date, access token and refresh token. the problem is the token is expired before the given time that i got from the server. so i figure out that there is an interval between the time of the server and the time of the iPhone. when i looked at the code of the SDK facebook there is no logic to handle this issue, it's a simple comparison. so my question is this issue from server side i mean the implementation of OAuth is incorrect or it's an issue from the client side?
Facebook Code:
- (BOOL)isSessionValid {
return (self.accessToken != nil && self.expirationDate != nil
&& NSOrderedDescending == [self.expirationDate compare:[NSDate date]]);
}
My code :
// Get the remaining period of the token to expire and subtract 30 sec
int delay = ([expirationDate timeIntervalSinceDate:serverDateTaken] - 30);
// Save the new Expiring date
objectOAuth.expiresIn = [[[NSDate date] dateByAddingTimeInterval:delay] description];
+ (BOOL)isSessionValid
{
// Get expiration date
OAuth *authParam = [Connection getSessionParameters];
// Formating
static NSString *timeZone = #"UTC";
NSDate *expirationDate = [Connection getDateFromString:authParam.expiresIn withTimeZone:timeZone];
// get the remaining period
int diff = [expirationDate timeIntervalSinceNow];
// Check if it's expired
return (diff <= 0);
}
Unfortunately there isn't really any good mechanism to check the time skew between the client and the server. I would stick with the simple check since there is less code that needs to be maintained and debugged. And no matter how much you check, you will still need to handle getting back a TOKEN EXPIRED error.

FBGraph and FQL use to get the friends contact number and emailID in iphone

I am using Facebook API to get the contact number and email id of friends, I worked on fbgraph and fql and uses all queries from https://developers.facebook.com/docs/reference/fql/, but in forum page of facebook I found there is no way to get the contact number and email ID.
I also used the extended permission of the Facebook API but I didn't find anything.
If anyone know about it then please give the answer ...
answer will be appreciated...
Thanks in advance!!!!!
If you use this code with the users access token
var url = "https://graph.facebook.com/me/?access_token=" + token;
var req = new XMLHttpRequest();
req.open("get", url, true);
req.send(null);
req.onerror = function () { alert("Error"); };
Then you will find the req.responseText has all the user information you are after. You can also get the user access token once they login.
Make sure you have the "email" permission when the user authenticates
NSArray *permissions = [NSArray alloc] initWithObjects:#"permissions",nil];
[facebook authorize:permissions];
[permissions release];
Then, when the user has logged in, get the "me" from the graph:
[facebook requestFromGraph:#"me/" withDelegate:self];
You get the information from the "requestDidLoad" callback method:
if([result objectForKey:#"first_name"]){
// do stuff w/ user info
}
The id is:
[request objectForKey:#"id"];

RestKit request seems to work only once

Alright I've been debugging the whole day but can't figure out what the problem is with my code.
The goal is to send a POST with RestKit to the Heroku API with a username/password to retrieve the API key.
The problem is that I'm only able to sent the request once. When sending the request the second time I get errors. (So first time I do get the API key binded to my object, but the second time just a error)
I'm using the current version of RestKit (0.10)
The code:
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObject:(id)object
{
Account *account = (Account *)object;
NSLog(#"API_KEY: %#", account.apiKey);
}
- (IBAction) login:(id)sender
{
Account *account = [[Account alloc] init];
account.email = [emailField text];
account.password = [passwordField text];
[[RKObjectManager sharedManager] postObject:account delegate:self];
}
LOG
/// ---> FIRST CLICK
2012-05-25 14:57:00.028 HerokuApp[11154:fb03] API_KEY: 1234567890
/// ---> SECOND CLICK
2012-05-25 14:57:03.427 HerokuApp[11154:fb03] W restkit.network:RKObjectLoader.m:281 Unable to find parser for MIME Type 'text/html'
2012-05-25 14:57:03.427 HerokuApp[11154:fb03] W restkit.network:RKObjectLoader.m:309 Encountered unexpected response with status code: 200 (MIME Type: text/html -> URL: https://api.heroku.com/login -- https://api.heroku.com -- https://api.heroku.com -- https://api.heroku.com)
2012-05-25 14:57:03.429 HerokuApp[11154:fb03] didFailWithError: Error Domain=org.restkit.RestKit.ErrorDomain Code=4 "The operation couldn’t be completed. (org.restkit.RestKit.ErrorDomain error 4.)"
Can anybody help me explaining why this behaviour is occuring?
Perhaps the API behaves differently when you are logged in. From your log messages, it is appearing to return back text/html content, and not something that RestKit knows how to deal with.
Run in the simulator on a machine where Wireshark is capturing packets. Reproduce the error, then find the TCP stream where this is happening and look at it. If you need help, update your question with the result of "Follow Stream" in Wireshark so that we can see the full HTTP traffic.

Could I Extend Facebook Access_Token Expiration Time without Single Sign-On?

I am a newbie on integrating facebook to iphone.
Now I encounter a problem when removing offline_access. Who can give me a hand? please
I use following code to get facebook authorization.
[facebook dialog:#"oauth" andParams:params andDelegate:self];
While when I extend access token with following code:
[facebook extendAccessTokenIfNeeded];
I encounter error: error_msg=The access token was not obtained using single sign-on, error_code=10
If I use following code to get authorization, I can extend access token.
[facebook authorize:permissions];
But I don't want my app directe to safari and then redirect to my app to get authorization
I see in Removal of offline_access permission, it says
Scenario 4: Client-side OAuth and Extending Access_Token Expiration Time through New Endpoint
Could I use it?
If yes, how to use it?
If no, is there any other method to extend access token? (without redirecting to safari)
{request_args=(
{
key = method;
value = "auth.extendSSOAccessToken";
},
{
key = sdk;
value = ios;
},
{
key = "sdk_version";
value = 2;
},
{
key = "access_token";
value = AAAAAK9pJJuEBAJ5VBsWIMjfdv6s9q6bXjO4AdO3diZA6s9ABEqS1VHNG1N5ynbvxyXVrFxTZAQ4RS8vww5hFPgb86TamBD0yjqPN75xopr8ACwqu8X;
},
{
key = format;
value = json;
}
), error_msg=The access token was not obtained using single sign-on, error_code=10}