Question

I'm using sdk 3.7
My Android application doen't use FB authentication, but I have a share button.

On this button click, I trying to create a session and open a FB WebDialog, when I do that I'm getting dialog that asks me for publish permission and after that the Session doen't opened and I'm getting com.facebook.FacebookAuthorizationException: UnknownError: ApiException:The app must ask for a basic_info permission at install time.

I tried:
1. to add 'basic_info' permission. 2. to uninstall my app and the fb app and install again.

How solve this problem?
(see my code below)

    @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);

            boolean isFacebookResponse =
                    Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
            if (isFacebookResponse) {

            }
        }

        @Override
        public void onFacebookShareClick() {
            checkFacebookLogin();
        }

/**
     * Login to FB if needed
     */
    private void checkFacebookLogin() {
        Session session = Session.getActiveSession();
        try {
            if (session == null || session.getState() != SessionState.OPENED) {
                logInToFacebook();
            } else {
                publishFeedDialog();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * login to facebook
     */
    private void logInToFacebook() {
        String app_id = getString(R.string.app_id);

        Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);

        Session session = new Session.Builder(this)
                .setApplicationId(app_id)
                .build();
        session.addCallback(this);
        Session.setActiveSession(session);

        List<String> PERMISSIONS = Arrays.asList("publish_actions");

        // Login
        if (!session.isOpened() && !session.isClosed()) {
            session.openForPublish(new Session.OpenRequest(this)
                    .setPermissions(PERMISSIONS)
                    .setCallback(this));
        } else {
            Session.openActiveSession(this, true, this);
        }
    }

    /**
     * Disconnect from facebook
     */
    public void logOut() {
        Session session = Session.getActiveSession();
        if (!session.isClosed()) {
            session.closeAndClearTokenInformation();
        }
    }

    @Override
    public void call(Session session, SessionState state, Exception exception) {
        if (state == SessionState.OPENED) {
            publishFeedDialog();
        }

        if(exception !=null){
            exception.printStackTrace();
        }
    }

    private void publishFeedDialog() {
        Bundle params = new Bundle();
        params.putString("name", "test name");
        params.putString("caption", "test caption");
        params.putString("description", "test description");
        params.putString("link", "test link");
        params.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");

        WebDialog feedDialog = (
                new WebDialog.FeedDialogBuilder(this,
                        Session.getActiveSession(), params))
                .setOnCompleteListener(new WebDialog.OnCompleteListener() {

                    @Override
                    public void onComplete(Bundle values, FacebookException error) {
                        if (error == null) {
                            // When the story is posted, echo the success
                            // and the post Id.
                            final String postId = values.getString("post_id");
                            if (postId != null) {
                                //DebugToast.show(getApplicationContext(), "Posted story, id: " + postId);
                            } else {
                                // User clicked the Cancel button
                                //DebugToast.show(getApplicationContext(), "Publish cancelled");
                            }
                        } else if (error instanceof FacebookOperationCanceledException) {
                            // User clicked the "x" button
                            //DebugToast.show(getApplicationContext(), "Publish cancelled");
                        } else {
                            // Generic, ex: network error
                            //DebugToast.show(getApplicationContext(), "Error posting story");
                        }

                        logOut();
                    }
                })
                .build();
        feedDialog.show();
    }
Was it helpful?

Solution

I'm not sure, I didn't build a project with FB API, not yet but I will try to help you. As far as I can read, you need to separate the request of read and publish permissions.

According to the FB API Docs:

Apps should separate the request of read and publish permissions. Plan your app around requesting the bare minimum of read permissions at initial login and then any publish permissions when a person actually needs them.

So, your code might be:

/*
 * login to facebook
 */
private void logInToFacebook() {
    //...
    if (!session.isOpened() && !session.isClosed()) {
        session.openForRead(new Session.OpenRequest(this)
                .setPermissions(Arrays.asList("basic_info"))
                .setCallback(this));
    } else {
        Session.openActiveSession(this, true, this);
    }
}

/*
 * set the publish_actions permission here
 */
private void publishFeedDialog() {
    Session session = Session.getActiveSession();
    // check the session
    if (session != null){
        // create a new permission
        Session.NewPermissionsRequest newPermissionsRequest = new Session
                .NewPermissionsRequest(this, Arrays.asList("publish_actions"));
        // set a new publish permission request
        session.requestNewPublishPermissions(newPermissionsRequest);

        Bundle params = new Bundle();
        //...   
    }
}

Maybe this answer might help you with this: SSO (Singe Sign-On) not working when Facebook app is installed on device: he does this on the call method and he said:

Since call() gets called anytime there is a change in the Session, the session.isOpen() will be true, if we do not check if the permission is set, we will enter in an infinite loop.

You have this information about requestNewPublishPermissions on the docs:

This method is used to request permissions in addition to what the app has already been granted. This happens after an initial connection has been made to Facebook.

I saw this solution on this step: Add Publishing Logic hence you can read:

The method will first check if the logged-in user has granted your app publish permissions; if they have not, they will be prompted to reauthorize the app and grant the missing permissions.

I hope this will help you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top