How to get access token from FBSession? - ios

I am using the Facebook SDK in order to get user groups in an application
but I am getting a null access token.
My code in viewDidLoad is as follows.
- (void)viewDidLoad
{
[super viewDidLoad];
self.session = [[FBSession alloc] initWithAppID:appID permissions:#[#"basic_info",#"user_groups",#"email"] defaultAudience:FBSessionDefaultAudienceEveryone urlSchemeSuffix:nil tokenCacheStrategy:nil];
[FBSession openActiveSessionWithReadPermissions:#[#"basic_info",#"user_groups",#"email"] allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
NSLog(#"Error in Session Opening %#",error.description);
NSLog(#"access Token %#",session.accessTokenData.accessToken);
[FBRequestConnection startWithGraphPath:#"me/groups" parameters:nil HTTPMethod:#"GET" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"%#",result);
}else
{
NSLog(#"Error %#",error.description);
}
}];
}];
}
OUTPUT of this code is :-
Error in Session Opening (null)
access Token (null)
Error Error Domain=com.facebook.sdk Code=5 "The operation couldn’t be completed. (com.facebook.sdk error 5.)" UserInfo=0x1090acc80 {com.facebook.sdk:HTTPStatusCode=400, com.facebook.sdk:ParsedJSONResponseKey={
body = {
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
};
code = 400;
}}
As you can see the access token is null..
What am I doing wrong ?
Is there something extra which should be added in this code ?
Thanks

you want this:
session.accessTokenData.accessToken
where 'session' is your FBSession
which you can get from...
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded)
{
// If there's one, just open the session silently, without showing the user the login UI
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile", #"email"]
allowLoginUI:NO
completionHandler:^(FBSession *session, FBSessionState state, NSError *error)
{
NSLog(#"%#", session.accessTokenData.accessToken);
}];
}

Are you using the correct facebook appID? Why not specify nil, i.e.,
self.session = [[FBSession alloc] initWithAppID:nil permissions:#[#"basic_info",#"user_groups",#"email"] defaultAudience:FBSessionDefaultAudienceEveryone urlSchemeSuffix:nil tokenCacheStrategy:nil];
That'd be one less place to go wrong. As it says in FBSession class reference
If nil is passed in the default App ID will be obtained from a call to
<[FBSession defaultAppID]>. The default is nil.
Also, you don't have to alloc/init the FBSession yourself, but if you want to, you should follow the 3-step process specified in FBSession lifecycle, including checking for FBSessionStateCreated before proceeding with one of the open methods, as quoted from FBSession lifecycle:
Instead of calling one of the static openActiveSession* methods, your app can achieve the same flow following these steps:
Call one of the FBSession instance init functions.
Check if the state value has transitioned to FBSessionStateCreated.
If the state value is FBSessionStateCreated, call one of the
FBSession instance
open functions.

Related

Facebook Graph API Call Without Using User Login

I am working on getting posts from a public Facebook page using the Facebook Graph API, without the user logging in. Using the steps from here I got the Token I would need since the end-user is not logging in, and the page is public. In my app, I have the following:
-(IBAction)testing {
NSString *token = #"MYAccessToken";
FBSession* session = [[FBSession alloc] initWithPermissions:#[#"manage_pages"]];
FBAccessTokenData* tokenData =
[FBAccessTokenData createTokenFromString:token
permissions:#[#"manage_pages"]
expirationDate:nil
loginType:FBSessionLoginTypeNone
refreshDate:nil];
[session openFromAccessTokenData:tokenData completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if ([session isOpen]) {
[self performGraph];
}
}];
}
-(void)performGraph {
NSLog(#"Go");
[FBRequestConnection startWithGraphPath:#"/{your-page}/posts"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
NSLog(#"Result%#", result);
/* handle the result */
}];
}
It runs the method performGraph as I can see it in my Console, leading me to believe that the FBSession must be open, since that is where it runs it. However, I get the following error message in FBSDKLog: Error for request to endpoint '/{your-page}/posts': An open FBSession must be specified for calls to this endpoint.
If the FBSession isn't open, it shouldn't be even attempting to perform the Graph API call, yet it tells me it needs an open FBSession. Can someone help me out here a bit?
As provided by the documentation for startWithGraphPath:parameters:HTTPMethod:completionHandler: that method uses the [FBSession activeSession], and since you're creating a new session object, it is NOT the activeSession, which is why you're effectively calling the graph API with a nil session.
You can either set the session you created as the activeSession by calling FBSession.activeSession, or you can create an FBRequest object with your session instance, and then create a FBRequestConnection with the FBRequest.

Facebook Access Token is null when posting score to Facebook Leader through iPad

I am using Facebook Leader to post score that is working fine in the iOS 7 when I use iPhone but it is giving null Access token when I use iPad with iOS 7.When I used older version iPad then also it was working fine.I am getting this issue only when I use iPad with iOS.
Code Snippet:
[FBSession openActiveSessionWithPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceFriends allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
NSLog(#" access==%#",[FBSession activeSession].accessTokenData.accessToken);
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[FBSession activeSession].accessTokenData.accessToken,#"access_token",[NSString stringWithFormat:#"%d",time], #"score",nil];
[FBRequestConnection startWithGraphPath:#"me/scores"
parameters:params
HTTPMethod:#"POST"
completionHandler:
^(FBRequestConnection *connection, id result, NSError *error) {
// Handle results
NSLog(#"result==%# eror==%#",result,error);
}];
}];
Error Message:
Error Domain=com.facebook.sdk Code=5 "The operation couldn’t be completed. (com.facebook.sdk error 5.)" UserInfo=0x16573530 {com.facebook.sdk:ParsedJSONResponseKey={
body = {
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
};
code = 400;
}, com.facebook.sdk:HTTPStatusCode=400}
I am stuck here.please suggest some way out.Is anything wrong with my implementation.
You should use session instead of [FBSession activeSession] because Currently in this Block method you are Quering access token form previous session i-e [FBSession activeSession] and not session that is returned from [FBSession openActiveSessionWithPublishPermissions:^block . Or At-least assign [FBSession setActiveSession:session]; before you get accesstoken.

I Only Get Facebook Active Access Token When Using iOS Facebook Integration

So when I am logged in to ios's facebook integration, my code works great. I get an active access token with permissions to read and write, and I have actually written to people's walls and whatnot from the app. However, when my app uses safari to authenticate people's login credentials, there is the common error: "An active access token must be used to query information about the current user."
What I don't understand is why I can only get my access code from the ios facebook integration. Anyways, my relevant code below is implemented by the current view controller when it loads:
if (![FBSession activeSession].isOpen) {
[self openSession];
}
my method openSession is defined as follows
- (void)openSession
{
//create the permissions array
NSArray *permissions =
[NSArray arrayWithObjects:#"email", #"basic_info", nil];
[FBSession openActiveSessionWithReadPermissions: permissions
allowLoginUI:YES
completionHandler: ^(FBSession *session, FBSessionState status, NSError *error) {
NSLog(#"\n\nopenSession called error = %#\n\n\n",error);
}];
}
I then go on to continue in the viewDidLoadMethod
[FBRequestConnection
startForMeWithCompletionHandler:^(FBRequestConnection *connection,
id<FBGraphUser> user,
NSError *error)
{
NSLog(#"error requestion connection: %#",error);
}];
I look forward to the response. Thanks in advance.
Using Facebook SDK.
NSString *fbAccessToken = [[[FBSession activeSession] accessTokenData] accessToken];
If you prefer dot syntax,
NSString *fbAccessToken = [FBSession activeSession].accessTokenData.accessToken;`
I hope , it will work for u

FBRequest requestForMe does not respond

I am following the sample codes on Facebook developer's site and I cannot fetch my name for example. I am using this code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
if (!appDelegate.session.isOpen) {
NSLog(#"Session is not open");
// create a fresh session object
appDelegate.session = [[FBSession alloc] init];
// if we don't have a cached token, a call to open here would cause UX for login to
// occur; we don't want that to happen unless the user clicks the login button, and so
// we check here to make sure we have a token before calling open
if (appDelegate.session.state == FBSessionStateCreatedTokenLoaded) {
// even though we had a cached token, we need to login to make the session usable
[appDelegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// we recurse here, in order to update buttons and labels
}];
}
} else {
NSLog(#"Session is open");
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
NSLog(#"logged in : %#, id: %#",user.name,user.id);
} else {
NSLog(#"error: %#", error);
}
}];
}
}
so when the session is open, I see this output:
Session is open
error: Error Domain=com.facebook.sdk Code=5 "The operation couldn’t be completed. (com.facebook.sdk error 5.)" UserInfo=0x1fd60620 {com.facebook.sdk:ParsedJSONResponseKey={
body = {
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
};
code = 400;
}, com.facebook.sdk:HTTPStatusCode=400}
On facebook app page, I have set AppId to 0 since it is not uploaded yet. BundleId is set correctly.
What am I missing or is there any other way to do so?
You should set your appDelegate.session as the active session by calling
[FBSession setActiveSession:appDelegate.session];
when you open it.
This is because FBRequest's requestForMe method uses the active session (as stated in the docs).

User cannot facebook log in again if they've deleted the facebook app in the past. Issue only arises from ios6.0 facebook integration [duplicate]

I'm using die Facebook SDK 3.1.1 to implement FB Connect in my iOS application. This works fine in the simple case with either the new FB integration (logged in on iOS) or falling back to the normal authorization via web view (I do not have the native Facebook application installed in both cases).
The problem occurs when I switch the account on iOS level. Logging out and logging in with a different FB user account.
To log in/authorize I perform:
[FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
If then get a FBSessionStateClosedLoginFailed every time even though I perform a closeAndClearTokenInformation when that state is reached:
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
NSLog(#"Session State Changed: %u", [[FBSession activeSession] state]);
switch (state) {
case FBSessionStateOpen:
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
NSLog(#"FBSessionStateClosedLoginFailed ERROR: %#", [error description]);
[[FBSession activeSession] closeAndClearTokenInformation];
break;
default:
break;
}
However, I receive the same state on every retry. My log says the following:
FBSDKLog: FBSession **INVALID** transition from FBSessionStateCreated to FBSessionStateClosed
FBSDKLog: FBSession transition from FBSessionStateCreated to FBSessionStateCreatedOpening
FBSDKLog: FBSession transition from FBSessionStateCreatedOpening to FBSessionStateClosedLoginFailed Session State Changed: 257
FBSessionStateClosedLoginFailed TOKEN: (null)
FBSessionStateClosedLoginFailed ERROR: Error Domain=com.facebook.sdk Code=2 "The operation couldn’t be completed. (com.facebook.sdk error 2.)" UserInfo=0xb24cc20 {com.facebook.sdk:ErrorLoginFailedReason=com.facebook.sdk:ErrorLoginFailedReason}
Can anyone reproduce this or has any idea where the problem might lie?
Another answer gives a way to manually resync the device with the server. I defined a method called fbRsync to call this code. Make sure to #import <Accounts/Accounts.h> in your implementation file and then define this method:
-(void)fbResync
{
ACAccountStore *accountStore;
ACAccountType *accountTypeFB;
if ((accountStore = [[ACAccountStore alloc] init]) && (accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){
NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
id account;
if (fbAccounts && [fbAccounts count] > 0 && (account = [fbAccounts objectAtIndex:0])){
[accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
//we don't actually need to inspect renewResult or error.
if (error){
}
}];
}
}
I then call fbResync if openActiveSessionWithReadPermissions yields an error:
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
if(error)
{
NSLog(#"Session error");
[self fbResync];
[NSThread sleepForTimeInterval:0.5]; //half a second
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
else
[self sessionStateChanged:session state:state error:error];
}];
The half a second delay is likely unnecessary, but it currently gives me piece of mind.
This seems to solve the problem for me. I can now switch between Facebook accounts and am able to log in. Yay!
I had the same problem. Check that your FB App is enabled in Settings -> Facebook.
Mine was disabled (even though I don't remember disabling it) and once I enabled it, it was fixed.
In my test process, I've added and removed my FB App several times from my FB Account, which is linked with my iPhone. It may explain why, magically, my app was disabled.
In ios 6 with fb sdk 3.1.1. Please pass permissions param as "nil or email" in "[FBSessio openActiveSessionWithReadPermissions..." method. Here my code it was works great.
#define IOS_NEWER_OR_EQUAL_TO_6 ( [ [ [ UIDevice currentDevice ] systemVersion ] floatValue ] >= 6.0 )
-(void)showFBLogin
{
[FBSession.activeSession closeAndClearTokenInformation];
NSArray *permissions = [NSArray arrayWithObjects:#"email, publish_actions, publish_stream", nil];
#ifdef IOS_NEWER_OR_EQUAL_TO_6
permissions = nil; or NSArray *permissions = [NSArray arrayWithObjects:#"email",nil];
#endif
NSLog(#"\npermissions = %#", permissions);
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
NSLog(#"\nfb sdk error = %#", error);
switch (state) {
case FBSessionStateOpen:
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
//success
}
}];
break;
case FBSessionStateClosed:
//need to handle
break;
case FBSessionStateClosedLoginFailed:
//need to handle
break;
default:
break;
}
}];
}
I have the same problem on 3.1.3 FB SDK with iOS7.1. And I find a solution here. Hope it help!!
I have tried all answers here.
#loganathan nil permissions, #ill_always_be_a_warriors fbResync.
All of those don't work for me.
But I found it will works well when I launch the same code in iPhone 7.1 simulator
(without SSO"Single Sign On")
The same code works well on old version iOS FB SDK(not sure which version, but not 3.13)
(but no SSO will show when try to login)
So, I try to re-write a sample problem. I found several different here.
1. https://developers.facebook.com/docs/ios/getting-started Add new FacebookDisplayName
2. I modify my BundleID for iTune connect but I am not update it back to Faceboook App Dev
After modify those setting, it works on my iOS app with SSO feature.
Hope it help!!
Did you Try the RenewSystemCredential Methods? Take a look at this post:
Facebook iOS SDK extendAccessToken not Working - fbDidExtendToken not being called
I got the same error. But i used #ill_always_be_a_warriors method: -(void)fbResync but not work for me.
I finally found it's my permissions issue, i removed offline_access permission, it works, hope it helps some one.

Resources