I am integrating logging in via Facebook in my app. I have this code that presents the login:
Session.openActiveSession(getActivity(), true, new Session.StatusCallback() {
// callback when session changes state
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Log.d("s", "SUCCES");
// make request to;2 the /me API
}
if (exception != null) {
Log.d("s", exception.toString());
}
Log.d("s", "state:" + state.toString());
}
});
After I enter my username/password, I get this in the logs:
D/app﹕ com.facebook.FacebookException: Log in attempt aborted.
D/app﹕ state:CLOSED_LOGIN_FAILED
D/app﹕ state:OPENING
What I've tried:
Checked my package name is correct
Checked the hash key is correct (Used the code by facebook)
Taken my app out of sandbox mode.
Checked I have the correct app id in my manifest file
What I am doing wrong?
Thanks!
I think you have this problem because you already have an active session. So just test it before trying to reopen it.
Session.StatusCallback statusCallback = new Session.StatusCallback() {
// callback when session changes state
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Log.d("s", "SUCCES");
// make request to;2 the /me API
}
if (exception != null) {
Log.d("s", exception.toString());
}
Log.d("s", "state:" + state.toString());
}
Session session = Session.getActiveSession();
if (session!=null && !session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this)
.setPermissions(...)
.setCallback(statusCallback));
} else {
Session.openActiveSession(getActivity(), true, statusCallback);
}
Reading through Facebook's SDK code we can extract some conclusions.
You get an exception on your callback with a specific message and state. These two are sent only when the close() Session's method is called, while the state was OPENING, which is at the same time called by setActiveSession, and that one gets called directly by your Session.openActiveSession(...)
The next thing that gets called is session.openForRead(openRequest), which calls open(openRequest, ...), with the current state being CREATED (default state after building a new session). This sets the new session as the active session through setActiveSession(session) which ends up closing the oldSession if there was one active, and here's the thing again, you are getting a FacebookException with a "Log in attempt aborted" on the message, which only gets called if the current state of the previous session was OPENING.
All that means that either you are calling this piece of code twice within a short amount of time or that the authorization process is not going through and ends up on a dead end (most likely).
Before getting deeper on the authorize method I'll double check configuration in facebook (mode, key hashes -different depending on the launching environment: production, degub, etc-, package name and start activity). For simplicity, clear data and caches of your app every time you try (or manually call closeAndClearTokenInformation() from your code.
Let's see what comes out to keep digging into the issue.
Related
Prompt how to correctly use the method openActiveSessionWithAccessToken() in Fasebook API. Authorization pass, get token, and launch a dialogue posting, it appears (I can post). After cleaning token, and a closed session, the method of closeAndClearTokenInformation() I'm trying to open a session already having previously received the token, and the session is opened, there is a dialogue, but alas, writes that an error occurred try again later.
In the dialog box displays:
An error occurred. Please try again later.
and gives an error in the log:
Error Code 110,
Error Description: Invalid user id,
Error Message: Missing user cookie (to validate session user).
Here's the code:
public static void migrateFbTokenToSession() {
AccessToken accessToken = AccessToken.createFromExistingAccessToken(getAccessToken(), new Date(getAccessExpires()), null, AccessTokenSource.FACEBOOK_APPLICATION_NATIVE, Arrays.asList(Constants.FB_APP_PERMISSIONS));
Session.openActiveSessionWithAccessToken(getContext(), accessToken , new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if(session != null && session.isOpened()) {
Session.setActiveSession(session);
}
}
});
}
You are removed preous session so how will you get access. You need to login again. If you want to maintain session then just use UiLifecycleHelper .
I did it with using createFromString method like this:
AccessToken accessToken = AccessToken.createFromString(savedTokenAsString, facebookPermissions, AccessTokenSource.NONE);
Session.openActiveSessionWithAccessToken(context, accessToken, new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) { }
});
But you need to make createFromString method public, because its package-private in facebook sdk.
Using the Android Facebook SDK 3.5, I have constant login problems: I receive CLOSED_LOGIN_FAILED with FacebookOperationCanceledException. I know there are about a million CLOSED_LOGIN_FAILED questions on SO but this one is different. Please, no answers about "are your key hashes OK? Is it out of sandbox? Is the app id OK?", because they are. :-) I tell you why I know they are:
If I disable SSO, I can log in using the more complicated, non-SSO approach. From that moment on, even if SSO is enabled again, it starts to work and there are no CLOSED_LOGIN_FAILED answers later. Same user, same keys, same app, same id, everything is the same. Non-SSO login is only needed once and then everything returns to normal. Not a single isolated case, I could reproduce it consistently with a couple of different accounts.
FacebookOperationCanceledException is received in spite of the user authorizing the access. The proper permissions are asked for (actually, a single publish_stream, nothing more), the authorization dialog is all right, I press OK, not Cancel, still I get that exception.
The code is straight from the tutorial. Some relevant parts for reference:
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
shareButton.setEnabled(true);
if (pendingPublishReauthorization && state.equals(SessionState.OPENED_TOKEN_UPDATED)) {
pendingPublishReauthorization = false;
publishStory();
}
}
else if (state.isClosed())
shareButton.setEnabled(false);
}
...
final LoginButton authButton = (LoginButton) findViewById(R.id.authButton);
authButton.setPublishPermissions(PERMISSIONS);
...
uiHelper = new UiLifecycleHelper(this, new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
});
...
#Override
public void onResume() {
super.onResume();
final Session session = Session.getActiveSession();
if (session != null && (session.isOpened() || session.isClosed()))
onSessionStateChange(session, session.getState(), null);
uiHelper.onResume();
}
I had a similar issue - I was getting CLOSED_LOGIN_FAILED with com.facebook.FacebookOperationCanceledException: User canceled operation and I definitely wasn't canceling the operation.
After a good 7-8 hours of toying with every line of my application code, I noticed that this was set on my activity in my manifest. Removing it solved it.
android:launchMode="singleInstance"
OR another option to try
It worked after I created an explicit app, SessionLoginSample, at developer.facebook.com. I copied the app id into the Android manifest, etc. and it worked. In other words, the Sample App configuration described in Facebook's Getting Started guide failed.
I have a viewpager and ActionBarSherlock. In the menu of the actionbar I placed a button "Log In" that takes me to a login screen (this is the same as the one in the tutorial). This login works fine, every time I open the app, I don't need to login again. What I want is to change this "Log in" menu item to "Log out" when the session is open. But the session is alwasy null. Not the state of the session, but the session itself. Why?
Session session = Session.getActiveSession();
if (session == null) {
} else {
publishStory();
}
What am I missing here? Do I need some other code, or should this be enough?
Because you need to open the active session before you can write Session.getActiveSession(). And don't forget to define session outside:
Session.openActiveSession(getActivity(), true, new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
}
});
session = Session.getActiveSession();
You can learn more about the related openActiveSession method here:
https://developers.facebook.com/docs/reference/android/current/Session
I am trying to restore user session inside my application. For that I call :
Session.openActiveSessionFromCache(ctx);
Most of the time it works fine. But sometimes I get :
java.lang.UnsupportedOperationException: Session: an attempt was made to open an already opened session.
Edit :
I've add this check :
Session activeSession = Session.getActiveSession();
if (activeSession!=null && activeSession.isOpened()){
return activeSession;
}
activeSession = Session.openActiveSessionFromCache(ctx);
and it did not help
Does anybody have a hint how to tackle that problem?
thanks
As the
openActiveSessionFromCache
works like following: "Create a new Session, and if a token cache is available, open the Session and make it active without any user interaction".
So it should be better if you check if the session is open or not before calling openActiveSessionFromCache. you can use
isOpened()
Use this line of code when facebook session is not in opened state.
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (!state.isClosed()) {
Session.openActiveSessionFromCache(ctx);
}
}
};
I can log in fine the first time. And I have an option where the user can disable facebook within the android application. When this is selected the facebook status goes to CLOSED. When I use the option again, to log back in the API hangs at OPENING within the callback function.
Per the examples I've found the first call uses
session.openForRead(new Session.OpenRequest(activity).setCallback(statusCallback));
and the second uses
Session.openActiveSession(activity, true, statusCallback);
The callback function looks like this:
private static class SessionStatusCallback implements Session.StatusCallback {
// callback when session changes state
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
GlobalVars.setUser(user.getName());
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(GlobalVars.getContext());
Editor editor = prefs.edit();
editor.putBoolean("facebook", true);
editor.commit();
System.out.println("facebook logged in");
}
}
});
}
System.out.println("facebook session state callback " + session.getState().toString());
}
}
I'm not sure if we have the exact problem, but my facebook's session state retains "OPENING" after the Session.openActiveSession(activity, true, statusCallback);. I had overridden the onActivityResult() inside my fragment. What I did to solve this was to override the method on my Activity instead.
Related answer: https://stackoverflow.com/a/13888652/782870