StatusCallback not called after requestNewReadPermissions then requestNewPublishPermissions

Pang picture Pang · Dec 26, 2012 · Viewed 15.7k times · Source

I am developing an Android App that integrates with Facebook. I would like to:

  1. Let the user login with Facebook
  2. Get the user's email address on Facebook (could be a proxied email address, which is fine)
  3. Post to the user's wall/timeline on his/her behalf

Technically, that would be to:

  1. Authenticate the user
  2. Request the email permission
  3. Request the publish_stream permission

1. Authenticate the user

I called Session.openActiveSession() with a Session.StatusCallback (I already checked that there is no active opened session beforehand):

final Session.StatusCallback sessionStatusCallback = new Session.StatusCallback() {
    public void call(final Session session, SessionState state, Exception exception) {
        // If there is an exception...
        if(exception != null)
        {
            // Handle fail case here.
            return;
        }

        // If session is just opened...
        if(state == SessionState.OPENED)
        {
            // Handle success case here.
            return;
        }
    };
};

// Start Facebook Login.
Session.openActiveSession(activity, true, sessionStatusCallback);

My callback is called after successful login. So far so good.

2. Request the email permission

This is my status callback:

new Session.StatusCallback() {
    public void call(final Session session, SessionState state, Exception exception) {
        // If there is an exception...
        if(exception != null)
        {
            // Handle fail case here.
            return;
        }
        
        // If token is just updated...
        if(state == SessionState.OPENED_TOKEN_UPDATED)
        {
            // Handle success case here.
            return;
        }
    };
};

I request the permission with Session.requestNewReadPermissions():

final Session session = Session.getActiveSession();
final static String[] PERMISSION_ARRAY_READ = {"email"};
final List<String> permissionList = Arrays.asList(PERMISSION_ARRAY_READ);

// If all required permissions are available...
if(session.getPermissions().containsAll(permissionList))
{
    // Handle success case here.
    return;
}

// Request permissions.
session.requestNewReadPermissions(new Session.NewPermissionsRequest(activity, permissionList));

My callback is called after permission is granted. So far so good.

3. Request the publish_stream permission

This is my status callback:

new Session.StatusCallback() {
    public void call(final Session session, SessionState state, Exception exception) {
        // If there is an exception...
        if(exception != null)
        {
            // Handle fail case here.
            return;
        }
        
        // If token is just updated...
        if(state == SessionState.OPENED_TOKEN_UPDATED)
        {
            // Handle success case here.
            return;
        }
    };
};

I request the permission with Session.requestNewPublishPermissions():

final Session session = Session.getActiveSession();
final static String[] PERMISSION_ARRAY_PUBLISH = {"publish_stream"};
final List<String> permissionList = Arrays.asList(PERMISSION_ARRAY_PUBLISH);

// If all required permissions are available...
if(session.getPermissions().containsAll(permissionList))
{
    // Handle success case here.
    return;
}

// Request permissions.
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(activity, permissionList));

This time, my callback is not called after permission is granted.

Investigation

Upon further investigation, I found that my callback is triggered by com.facebook.Session#postStateChange(SessionState, SessionState, Exception):

void postStateChange(final SessionState oldState, final SessionState newState, final Exception exception) {
    if (oldState == newState && exception == null) {
        return;
    }

    /* ... */
}

Since oldState and newState are equal (both being SessionState.OPENED_TOKEN_UPDATED, my callback is not called.

Question

How can I receive any notification after permission is granted for the 2nd time? Am I supposed to close() the session and re-open it from cache?

Additional info

My Facebook Android SDK 3.0 is download from here, which is stated in Facebook's Getting Started with the Facebook SDK for Android.

Answer

rightparen picture rightparen · Dec 26, 2012

This is a bug.

[edit: As Guy points out in comments, this was fixed in 3.0.1, so this workaround is no longer necessary]

The workaround you mention is basically correct, though you do not need to call close. If you are using the single active session, before calling requestNewPublishPermissions() just call:

Session.openActiveSessionFromCache(myContext);

If you are using multiple sessions, you need to initialize a new Session with the TokenCachingStrategy, verify it is in the CREATED_TOKEN_LOADED state, and call openForRead(null);

After doing one of these, requestNewPublishPermissions() should call your notification once it completes.