I'm not sure if this is your problem, but I had some weird issues when I didn't update to the latest facebook-ios-sdk. The latest version, 3.5.1, has a different location for the access token: FBSession.activeSession.accessTokenData.accessToken. Facebook's api is a sometimes a tad quirky, so I would definitely try updating the sdk first.
–
Mr. TMay 16 '13 at 22:07

Also, your access token is valid. In the future if you wanted to double check, you can always check to see if your access token is correct (and thus something else is broken) by going directly to the graph api. To check, in a browser go to something like graph.facebook.com/…
–
Mr. TMay 16 '13 at 22:10

Thanks so much for the reply! Unfortunately updating the FB SDK did not help fix the token not found problem :(
–
DavodaMay 16 '13 at 23:24

if you made a simpler FBRequest, does it work? like instead of going to "me/mydogwoofs:posted", you went to just "me", does it work?
–
Mr. TMay 18 '13 at 0:17

I'm not certain that this is causing your problem, but I've had issues in the past with the Facebook SDK's aggressive caching. Because the Facebook SDK looks to multiple places for a valid logged in Facebook user, it short-circuits this search on subsequent calls by caching the current logged in user. If at any point one of the possible logged in Facebook user changes, or auth for that user changes, then things can go a bit crazy.

To give you an idea, the Facebook SDK tries the iOS 5+ system facebook account, inter-app calls to facebook's own native app, the browser cookie for the web view instance running in your app, or bounce you out to safari and use the browser cookie in safari... so if any one of those different logged in accounts changed, or one of those accounts revoted permissions or changed its password (for example), things can go haywire if the SDK cached too aggressively. In order to get around this, I always checked the access token against the graph api after I open a Facebook SDK session. If it passes the simple "me" test, then I'll accept this access token as valid and proceed. However, if it fails, then I flush the cached values in the SDK and force the Facebook SDK to re-open a brand new session, which would go back through all of the possible logged in Facebook accounts to find an active session. This may or may not result in a new application authentication prompt... however it should result in a working access token for you app.

Some sample code

To help you understand what I'm doing, here's some semi-pseudo code. (Unfortunately, I've abstracted away too many things to be able to easily copy-paste a working set of code here, so you'll have to fill in the blanks in a few places :P)

Main run loop

The entry point to my Facebook code starts with this if statement that looks at the current state of the Facebook SDK activeSession and either reprompts or verifies access:

if (isSet(FBSession.activeSession) &&
(FBSession.activeSession.isOpen || FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded))
{
// Make sure the access_token is still authed and has the correct permissions first (can't trust what's cached by fb's sdk)
[self checkAgainstGraphAPIOnVerified:^
{
// From the api the access_token looks ready, make sure fb sdk session is open as well
if (FBSession.activeSession.isOpen)
{
// We're authenticated and session is open, good to go
[self runIfFullAuth];
}
else if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded)
{
// We have a cached token (permissions all look good), we need to re-open the fb sdk session
[FBSession.activeSession openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent
completionHandler:openSessionHandler];
}
}
onInvalidated:^
{
// App isn't removed, but don't have required permissions anymore...
if (FBSession.activeSession.isOpen)
{
// We have an open fb session, so just reprompt for permissions
[self repromptForPermissions];
}
else if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded)
{
// We have a cached token, we need re-open the session first before reprompting
[FBSession.activeSession openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent
completionHandler:openSessionHandler];
}
}
onAppRemoved:^
{
// App is completely removed, so prompt for permissions
[self openNewFBSession];
}];
}
else
{
// No valid access_token cached, prompt for permissions
[self openNewFBSession];
}

Most of the functions that are called should be pretty straight forward. For instance, runIfFullAuth just calls whatever you want after the user has been fully authed and you have a verified access token. checkAgainstGraphAPIOnVerified:onInvalidated:onAppRemoved: is my own function that does a simple call out to graph.facebook.com/me?fields=permissions with the access token FBSession.activeSession.accessTokenData.accessToken. If I get an id back in the json returned, then I have a verified access token. If I'm missing any required permissions in the json returned, then I have an invalidated access token. If I get nothing back from the graph api, then I consider that as the app being removed.

openSessionHandler

openSessionHandler is responsible for understanding what the Facebook SDK is returning to us after we request for an open session. Here's roughly what it's doing:

To be honest, I don't know if that second call to close is redundant... but this is how I've always done it.... hahaha

Oh, and at the top of my function openNewFBSession, which I call whenever I need to force the Facebook SDK to start over and search for a new Facebook session, I call my clearCachedFBInfo function. That guarantees I have no cached Facebook information in the SDK, and then I go and open a new session.

In the end, I still don't know if this is causing the problem that you're seeing, but I've definitely experienced very nasty issues with seemingly valid access tokens that are not valid in the past, and this is how I fixed my problems. Good luck! And I'm happy to answer any questions that you may have!