Session.isOpened() == true but Session.getAccessToken() == ""
Asked Answered
A

3

16

In my app, I'm trying to authenticate (login) by passing Facebook session information (token and expiration date) to my server.

My login sequence to the app server is as follows:

  1. Get active facebook session.
  2. If the session is valid, get token and send it on to the server.

And in code:

Session session = Session.getActiveSession();
if(session != null && session.isOpened() && !didLogin) {
    didLogin = true;
    String token = session.getAccessToken();
    Date expires = session.getExpirationDate();
    loginWithFacebookSession(token, expires);
}

I have noticed that suddenly, after a few months of this working just fine, the information being sent to the server is occasionally not valid, specifically the token is an empty string and the expires is an invalid date.

After going a bit through the Facebook SDK (version 3.0.1), I spotted what is probably the basis of my error:

private static final Date MIN_DATE = new Date(Long.MIN_VALUE);
private static final Date ALREADY_EXPIRED_EXPIRATION_TIME = MIN_DATE;
private static final Date DEFAULT_LAST_REFRESH_TIME = new Date();

static AccessToken createEmptyToken(List<String> permissions) {
    return new AccessToken("", ALREADY_EXPIRED_EXPIRATION_TIME, permissions, AccessTokenSource.NONE,
            DEFAULT_LAST_REFRESH_TIME);
}

This means that somewhere along the way, the Facebook SDK is creating an empty token and returning it with a SessionState.Category.OPENED_CATEGORY.

Why is session.isOpened() returning true when in fact there is no accessToken information? Should I be checking a different property? Is this a bug in Facebook's SDK?

EDIT:
Reported this to Facebook at: https://developers.facebook.com/bugs/121924628017965

Audry answered 17/6, 2013 at 6:59 Comment(9)
How are you opening the sessions/setting the active session?Pinnatiped
I'm using the UiLifecycleHelper class as documented in the Facebook developers websiteAudry
Maybe you have to check if the session is in the OPENED_TOKEN_UPDATED state, that is the token has changed, but the session is still in an opened state.Truong
welcome to the FacebookSDK...Opiumism
I am getting session as null, while running native fb app in background. What will be the issue?Gunilla
How did you solved this ?Tumblebug
@ReneDohan - we noticed that this happens only on specific versions of facebookAudry
You mean facebook sdk of facebook app ? I have problems reproducing this issue and I am looking to workaround as it seems that UiLifecycleHelper is not enough to have updated token in active session... Maybe Session.openActiveSessionFromCache(context()) could help ? I have to reproduce it somehow , both testers have this issue but not me...Tumblebug
it was an issue with clients that have an outdated Facebook application installed.Audry
A
2

Use this method and check if your hash is correct

public void getHashKeyForFacebook(Activity activity, String packageName){
    try{
        PackageInfo info = activity.getPackageManager().getPackageInfo(packageName,  PackageManager.GET_SIGNATURES);

        for (Signature signature : info.signatures){
                MessageDigest md = MessageDigest.getInstance("SHA");
                md.update(signature.toByteArray());
                Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
        }
    } catch (Exception ex){

    }
}
Andorra answered 7/9, 2013 at 5:53 Comment(1)
the key hash was correct, this doesn't answer this question but othersAudry
D
1

Apart from the Facebook SDK being like voodoo magic, there are some thing you are doing that I do not do in my auth flow. I'm assuming here that your code snippet is not in the Session.StatusCallback call function. No matter what, I always open the session for read before accessing the token from the callback. This request just inconveniences the user for a few milliseconds with a loading spinner before it returns. It also helps in case when the user has deleted the permissions from their Facebook settings page.

My auth flow is something like this:

private void startFbAuth() {
    Session session = Session.getActiveSession();
    if (session == null) {
        session = new Session(getApplicationContext());
        Session.setActiveSession(session);

        Session.OpenRequest openReadRequest = new Session.OpenRequest(this);
        openReadRequest.setPermissions(Arrays.asList({ "email" }));
        openReadRequest.setCallback(statusCallback);

        Session.NewPermissionsRequest permissionReadRequest = new Session.NewPermissionsRequest(this, Arrays.asList(EMAIL_PERMISSIONS));
        permissionReadRequest.setCallback(statusCallback);

        if (!session.isOpened() && !session.isClosed()) {
            session.openForRead(openReadRequest);
        } else {
            session.requestNewReadPermissions(permissionReadRequest);
        }
    }

    private Session.StatusCallback statusCallback = new SessionStatusCallback();

    private class SessionStatusCallback implements Session.StatusCallback {
        @Override
        public void call(Session session, SessionState state, Exception exception) {
            if (session.isClosed()) {
                session.closeAndClearTokenInformation();
                Session.setActiveSession(null);
                SessionStore.clearFacebookInformation(Activity.this);
                // Either throw an error or try reconnecting by calling startFbAuth
            }
            if (exception != null) {
                session.closeAndClearTokenInformation();
                Session.setActiveSession(session);
                // Either throw an error or try reconnecting by calling startFbAuth
            } else {
                if (session.isOpened()) {
                    String token = session.getAccessToken();
                    // It shouldn't be null or empty here
                }
            }
        }
    }
Dalmatic answered 26/6, 2013 at 5:48 Comment(1)
And what if session is not null , like op's case... I dont get point with this code example...Tumblebug
R
0

I Solved the problem. The problem was in key Hash.

Follow this tutorial

go to step no. 4 Run the Samples.

at last you will found Troubleshooting section and that is the solution.

Thanks! https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/

Rakel answered 20/6, 2013 at 10:19 Comment(1)
it has nothing to do with the hash-key. the app is fine, it's the phone, the app the SDK.Audry

© 2022 - 2024 — McMap. All rights reserved.