Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android facebook sdk - Session: an attempt was made to reauthorize a session that has a pending request

Tags:

Been banging my head agains the facebook-sdk-for-android-wall for the last couple of days now and need help. I can't find what's wrong, what I should do instead or how to check for some state that I'm missing.

My Android app is recording tracks and for a track the user have to option of posting the track summary to his/hers facebook timeline. I have got it to work as a happy flow but when testing different scenarios such as no internet connection etc I'm now stuck in a state where I only get the "Session: an attempt was made to reauthorize a session that has a pending request"-exception when trying to reauthorize permissions (even when internet connection is restored). I'm using the facebook SDK for android and SSO.

package com.test;

import java.io.Fil...
...

public class FaceBookUtil {

public interface FacebookPostCallback {
    void onComplete(String postId);
    void onError(Exception e);
    void onError();
}

private static final List<String> PERMISSIONS = Arrays.asList("publish_actions", "publish_stream");
private static final int REAUTH_ACTIVITY_CODE = 100;

public static void postToFaceBook(final Track track, final Activity activity, final FacebookPostCallback postCallback) {

    try {
        Session session = initFacebookSession(activity.getApplicationContext());
        Session.setActiveSession(session);

        StatusCallback statusCallback = new StatusCallback() {
            @Override
            public void call(Session session, SessionState state, Exception exception) {

                try {
                    // Check for publish permissions    
                    List<String> permissions = session.getPermissions();
                    if (!isSubsetOf(PERMISSIONS, permissions)) {
                        Session.ReauthorizeRequest reauthRequest = new Session
                                .ReauthorizeRequest(activity, PERMISSIONS)
                                .setRequestCode(REAUTH_ACTIVITY_CODE);
                        session.reauthorizeForPublish(reauthRequest);    //Here's where it breaks and the exceptions is thrown.
                        return;
                    }

                    Bundle postParams = new Bundle();
                    postParams.putString("name", "Facebook post test"); 
                    postParams.putString("caption", "Just a test"); 
                    postParams.putString("description", "A description");
                    postParams.putString("link", "http://www.google.com/");

                    Request.Callback reqCallback = new Request.Callback() {
                        public void onCompleted(Response response) {
                            String postId = null;

                            try {
                                FacebookException error = response.getError();
                                if (error != null)
                                    throw error;

                                JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();

                                postId = graphResponse.getString("id");
                                if (postId != null)
                                    postCallback.onComplete(postId);

                            } catch (Exception e) {
                                postCallback.onError();
                            }

                            if (postId == null)
                                postCallback.onError();
                        }
                    };

                    Request postRequest = new Request(session, "me/feed", postParams, HttpMethod.POST, reqCallback);
                    RequestAsyncTask task = new RequestAsyncTask(postRequest);
                    task.execute();

                } catch (Exception e) {
                    postCallback.onError(e);
                }
            }
        };

        if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED))
            session.openForRead(new Session.OpenRequest(activity).setCallback(statusCallback));

        else if (!session.isOpened() && !session.isClosed()) {
            OpenRequest req = new Session.OpenRequest(activity);
            req.setCallback(statusCallback);
            session.openForRead(req);

        } else {
            Session.openActiveSession(activity, true, statusCallback);

        }

    } catch (Exception e) {
        postCallback.onError(e);
    }    
}

private static boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
    for (String string : subset) {
        if (!superset.contains(string)) {
            return false;
        }
    }
    return true;
}

private static Session initFacebookSession(Context context) {

    Session session = Session.getActiveSession();

    if (session != null) 
        return session;

    /*
    if (savedInstanceState != null)
        session = Session.restoreSession(this, null, sessionStatusCallback, savedInstanceState);
    */

    if (session == null)
        session = new Session(context);

    return session;
}
}

If I debug into the android SDK I can see that the exception is thrown by the reauthorize method in the Session class because the pendingRequest is not null but I don't understand why, where it's set or how I can check for it, remove it or whet I'm supposed to do?

private void reauthorize(ReauthorizeRequest reauthorizeRequest, AuthorizationType authType) {
    validatePermissions(reauthorizeRequest, authType);
    validateLoginBehavior(reauthorizeRequest);
    if (reauthorizeRequest != null) {
        synchronized (this.lock) {
            if (pendingRequest != null) {   //Here's where the pendingRequest is already set and causes the exception...
                throw new UnsupportedOperationException(
                        "Session: an attempt was made to reauthorize a session that has a pending request.");
            }
            switch (this.state) {
                case OPENED:
                case OPENED_TOKEN_UPDATED:
                    pendingRequest = reauthorizeRequest;
                    break;
                default:
                    throw new UnsupportedOperationException(
                            "Session: an attempt was made to reauthorize a session that is not currently open.");
            }
        }

        authorize(reauthorizeRequest);
    }
}

I've googled the exception without any results, Any help is greatly appreciated.

On a side note I can probably refactor the whole FacebookUtil.postToFaceBook-method but while testing I've kept it in one method for readability.

like image 483
Cliffhanger Avatar asked Nov 07 '12 09:11

Cliffhanger


2 Answers

You need to call the onActivityResult() method on your current Session when asking for more permissions:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Logger.d(LOGTAG, "onActivityResult");
    if (RESULT_CANCELED == resultCode) {
        mAuthorizationCanceled = true;
    }
    **mFacebookSession.onActivityResult(this, requestCode, resultCode, data);**
}

This way the StatusCallback is called again and the pendingRequest is removed.

like image 85
PawelPredki Avatar answered Oct 16 '22 10:10

PawelPredki


Check to make sure you added this line of code in your Activity.

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data); 
    UiLifecycleHelper.onActivityResult();
} 
like image 37
Jesse Chen Avatar answered Oct 16 '22 11:10

Jesse Chen