80

The title says it all. I'm using a custom button to fetch the user's facebook information (for "sign up" purposes). Yet, I don't want the app to remember the last registered user, neither the currently logged in person via the Facebook native app. I want the Facebook login activity to pop up each time. That is why I want to log out any previous users programmatically.

How can I do that? This is how I do the login:

private void signInWithFacebook() {

    SessionTracker sessionTracker = new SessionTracker(getBaseContext(), new StatusCallback() 
    {
        @Override
        public void call(Session session, SessionState state, Exception exception) { 
        }
    }, null, false);

    String applicationId = Utility.getMetadataApplicationId(getBaseContext());
    mCurrentSession = sessionTracker.getSession();

    if (mCurrentSession == null || mCurrentSession.getState().isClosed()) {
        sessionTracker.setSession(null);
        Session session = new Session.Builder(getBaseContext()).setApplicationId(applicationId).build();
        Session.setActiveSession(session);
        mCurrentSession = session;
    }

    if (!mCurrentSession.isOpened()) {
        Session.OpenRequest openRequest = null;
        openRequest = new Session.OpenRequest(RegisterActivity.this);

        if (openRequest != null) {
            openRequest.setPermissions(null);
            openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);

            mCurrentSession.openForRead(openRequest);
        }
    }else {
        Request.executeMeRequestAsync(mCurrentSession, new Request.GraphUserCallback() {
              @Override
              public void onCompleted(GraphUser user, Response response) {
                  fillProfileWithFacebook( user );
              }
            });
    }
}

Ideally, I would make a call at the beginning of this method to log out any previous users.

Michael Currie
  • 13,721
  • 9
  • 42
  • 58
Michael Eilers Smith
  • 8,466
  • 20
  • 71
  • 106

9 Answers9

161

Update for latest SDK:

Now @zeuter's answer is correct for Facebook SDK v4.7+:

LoginManager.getInstance().logOut();

Original answer:

Please do not use SessionTracker. It is an internal (package private) class, and is not meant to be consumed as part of the public API. As such, its API may change at any time without any backwards compatibility guarantees. You should be able to get rid of all instances of SessionTracker in your code, and just use the active session instead.

To answer your question, if you don't want to keep any session data, simply call closeAndClearTokenInformation when your app closes.

ViliusK
  • 11,345
  • 4
  • 67
  • 71
Ming Li
  • 15,672
  • 3
  • 37
  • 35
  • Thanks for the answer. How do I get the current session without SessionTracker then? – Michael Eilers Smith Jan 14 '13 at 23:07
  • 3
    You just call Session.getActiveSession, and if it returns null, then you can either 1.) create a new Session using Session.Builder, and call Session.setActiveSession, or 2.) call one of the Session.openActiveSession methods (the static ones, which both opens and sets the active session for you). – Ming Li Jan 15 '13 at 17:33
  • 24
    And the fact that you have to open a session to logout shows how bad the Facebook SDK design is… Instead of offering a simple public API with standard Callbacks, you have to implement a crappy mechanism… amazing. – Martin Marconcini Nov 13 '13 at 03:57
  • I'm not sure I understand your statement. There are callbacks in the Session API. Would you care to elaborate? – Ming Li Nov 13 '13 at 18:19
  • 18
    Facebook SDK and documentation is pathetic! – Skynet Jan 29 '15 at 04:49
  • 3
    The official Facebook docs include code in examples which is deprecated - Then we have to refer to the good old stack inorder to un-deprecate the same. – Skynet Jan 29 '15 at 05:00
  • 1
    Rather than adding comments that do not contribute to the conversation, you should give specific examples where the documentation is lacking (pertaining to the question/answer), or you can go to the bottom of a particular documentation page on the developer portal, and click on the "No" button for "Was this document helpful?". – Ming Li Jan 29 '15 at 18:49
  • @MingLi per your link "This is an old version of the SDK. Check out the latest version." The "Session" class has been deprecated as of FB Android SDK 4.0 (https://developers.facebook.com/docs/android/change-log-4.x#ver4_00_0 "Session and UserSettingsFragment have been removed and replaced by the LoginManager and AccessToken classes."), and there seems to be no equivalent to do some of the things that Session could do. – swooby May 22 '15 at 02:30
  • Do you have a specific example of what you'd like to do? My answer was correct at the time it was posted since v4 of the SDK was release in March of this year. In this particular case, you can use the logout() method on LoginManager. – Ming Li May 26 '15 at 16:12
87

This method will help you to logout from facebook programmatically in android

/**
 * Logout From Facebook 
 */
public static void callFacebookLogout(Context context) {
    Session session = Session.getActiveSession();
    if (session != null) {

        if (!session.isClosed()) {
            session.closeAndClearTokenInformation();
            //clear your preferences if saved
        }
    } else {

        session = new Session(context);
        Session.setActiveSession(session);

        session.closeAndClearTokenInformation();
            //clear your preferences if saved

    }

}
Rikin Prajapati
  • 1,913
  • 2
  • 16
  • 23
66

Since Facebook's Android SDK v4.0 (see changelog) you need to execute the following:

LoginManager.getInstance().logOut();
Sufian
  • 6,405
  • 16
  • 66
  • 120
zeuter
  • 669
  • 5
  • 3
  • 8
    Thanks, but I am not seeing that this actually clears the session. LoginManager.logout() just internally calls "AccessToken.setCurrentAccessToken(null); Profile.setCurrentProfile(null);". I am seeing that the user can still log in without having to re-enter credentials the next time they launch the app. How do you force the user to re-enter their credentials? – swooby May 22 '15 at 02:34
  • This method helped me. After calling it and trying to re-login, an enter-credentials screen appeared, as expected. Thanks a ton. – Zsolt Boldizsar Jun 18 '15 at 19:21
  • 1
    As @swooby pointed, this solution unfortunately not works on apps using facebook sdk v4.x After made logOut, AccessToken is [{AccessToken token:ACCESS_TOKEN_REMOVED permissions:[public_profile]}] but AccessToken.getCurrentAccessToken().getToken() returns valid token string even if the user is not logged anymore or revoked the authorization to the app. – Lisitso Oct 09 '15 at 14:54
  • @Lisitso Do you know a solution for that now? – Jaec Aug 09 '16 at 19:51
  • 1
    @Jaec I used the solution provieded by "Aniket Thakur". You can find here among the other resposes. Cheers! – Lisitso Aug 10 '16 at 09:43
  • @swooby I have the same problem when logout. I want to remove credentials when logout from facebook. Did you solve this problem? – sersem1 Dec 25 '16 at 11:26
27

Here is snippet that allowed me to log out programmatically from facebook. Let me know if you see anything that I might need to improve.

private void logout(){
    // clear any user information
    mApp.clearUserPrefs();
    // find the active session which can only be facebook in my app
    Session session = Session.getActiveSession();
    // run the closeAndClearTokenInformation which does the following
    // DOCS : Closes the local in-memory Session object and clears any persistent 
    // cache related to the Session.
    session.closeAndClearTokenInformation();
    // return the user to the login screen
    startActivity(new Intent(getApplicationContext(), LoginActivity.class));
    // make sure the user can not access the page after he/she is logged out
    // clear the activity stack
    finish();
}
jpotts18
  • 4,951
  • 5
  • 31
  • 31
14

Since Facebook's Android SDK v4.0 you need to execute the following:

LoginManager.getInstance().logOut();

This is not sufficient. This will simply clear cached access token and profile so that AccessToken.getCurrentAccessToken() and Profile.getCurrentProfile() will now become null.

To completely logout you need to revoke permissions and then call LoginManager.getInstance().logOut();. To revoke permission execute following graph API -

    GraphRequest delPermRequest = new GraphRequest(AccessToken.getCurrentAccessToken(), "/{user-id}/permissions/", null, HttpMethod.DELETE, new GraphRequest.Callback() {
        @Override
        public void onCompleted(GraphResponse graphResponse) {
            if(graphResponse!=null){
                FacebookRequestError error =graphResponse.getError();
                if(error!=null){
                    Log.e(TAG, error.toString());
                }else {
                    finish();
                }
            }
        }
    });
    Log.d(TAG,"Executing revoke permissions with graph path" + delPermRequest.getGraphPath());
    delPermRequest.executeAsync();
Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
  • 2
    This is the correct answer to this question. `LoginManager.getInstance().logOut();` only clears the local cache, while the `GraphRequest` call programmatically revokes the app access from the user's Facebook account. *Both* are necessary. Neither is enough alone. – Yash Sampat Aug 28 '15 at 07:40
  • Where we have to put this code for delete permissions?! Code is not working in my case! Can you provide full code snippet sir.!? – Akshay Shinde Apr 01 '16 at 13:33
  • The code is working but giving warning: Request without access token missing application ID or client token. Do I need to add something to "/{user-id}/permissions/" in the code above? – zeeshan May 03 '16 at 18:11
  • @zeeshan replace {user-id} with me – Amritpal singh Nov 26 '18 at 10:25
8

Session class has been removed on SDK 4.0. The login magement is done through the class LoginManager. So:

mLoginManager = LoginManager.getInstance();
mLoginManager.logOut();

As the reference Upgrading to SDK 4.0 says:

Session Removed - AccessToken, LoginManager and CallbackManager classes supercede and replace functionality in the Session class.

felippe
  • 493
  • 6
  • 7
  • 1
    The answer of [zeuter](http://stackoverflow.com/a/29373122/995926) is shorter and points out the same api call. Why the duplicate? – rekire Aug 14 '15 at 13:32
3

Yup, As @luizfelippe mentioned Session class has been removed since SDK 4.0. We need to use LoginManager.

I just looked into LoginButton class for logout. They are making this kind of check. They logs out only if accessToken is not null. So, I think its better to have this in our code too..

AccessToken accessToken = AccessToken.getCurrentAccessToken();
if(accessToken != null){
    LoginManager.getInstance().logOut();
}
SureshCS50
  • 3,608
  • 1
  • 20
  • 27
  • The answer of [zeuter](http://stackoverflow.com/a/29373122/995926) is shorter and points out the same api call. Why the duplicate? – rekire Aug 14 '15 at 13:32
0
private Session.StatusCallback statusCallback = new SessionStatusCallback();

logout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Session.openActiveSession(this, true, statusCallback);  
}
});

private class SessionStatusCallback implements Session.StatusCallback {
@Override
public void call(Session session, SessionState state,
Exception exception) {
session.closeAndClearTokenInformation();    
}
}
selva_pollachi
  • 4,147
  • 4
  • 29
  • 42
0

Facebook provides two ways to login and logout from an account. One is to use LoginButton and the other is to use LoginManager. LoginButton is just a button which on clicked, the logging in is accomplished. On the other side LoginManager does this on its own. In your case you have use LoginManager to logout automatically.

LoginManager.getInstance().logout() does this work for you.

aravindkanna
  • 663
  • 1
  • 7
  • 25