android facebook GraphUser is always null - android

I have problem with code below. I try to log in with facebook to my app, when I use app with Activities this code works, but when I change it to Fragments it's stops work. When I first click on fb button I'm redirect to fb login but when I give username and pass, it doesn't go to onUserInfoFetched metod and doesn't directed me to ScreenFragment, and stay on the first fragment, and when I click the fb login button again in logcat shows me info "NOT_WORK" so user is null.
Could you help me with this?
loginBtn.setReadPermissions(permissions);
loginBtn.setUserInfoChangedCallback(new LoginButton.UserInfoChangedCallback() {
#Override
public void onUserInfoFetched(GraphUser user) {
if (user != null) {
getActivity().getFragmentManager().beginTransaction().
replace(android.R.id.content, new ScreenFragment()).addToBackStack(null).commit();
} else {
Log.d("FB", "NOT_WORK");
}
}
});

If you're using Fragments, you need to call
loginBtn.setFragment(this);
from within your Fragment implementation, and also override the onActivityResult method in your Fragment and pass it to the loginBtn.

Related

Android Facebook login always ask for user after logout

I am implementing a Facebook login with Facebook SDK on Android.
compile 'com.facebook.android:facebook-android-sdk:4.+'
I'm logging in with the user as
callbackManager = CallbackManager.Factory.create();
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
..
}
And for log out, I use my own log out button and log out the user programmatically:
LoginManager.getInstance().logOut();
My question is:
After log out, when I click on Continue with Facebook, the previous user information pops up to Continue as XY. I don't want this. I want to ask for email and password again, every time, if somebody wants to log in after log out. How can I do this?
Actually i found the solution. I changed the login behavior for the FB login button, for this i used:
loginButton.setLoginBehavior(LoginBehavior.WEB_ONLY);
So every time it pops up the WEB view for login button.
I want to ask for email, password again every time if somebody wants
to log in after log out.
try this in your onCreate()
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
updateWithToken(AccessToken.getCurrentAccessToken()); //add this method
Now in updateWithToken() method logout the user from previous session
private void updateWithToken(AccessToken currentAccessToken) {
if (currentAccessToken != null) {
LoginManager.getInstance().logOut();
} else {
}
}
EDIT
if you want to completely disconnect user from facebook login use:
public void disconnectFromFacebook() {
if (AccessToken.getCurrentAccessToken() == null) {
return; // already logged out
}
new GraphRequest(AccessToken.getCurrentAccessToken(), "/me/permissions/", null, HttpMethod.DELETE, new GraphRequest
.Callback() {
#Override
public void onCompleted(GraphResponse graphResponse) {
LoginManager.getInstance().logOut();
}
}).executeAsync();
}
To really disconnect from facebook with the android SDk and avoid auto login after you must use
val accessToken = AccessToken.getCurrentAccessToken()
val request = GraphRequest.newDeleteObjectRequest(accessToken, "me/permissions", { response ->
LoginManager.getInstance().logOut() //not really needed i think
})
request.executeAsync()
In response you have a responseCode == 200 if OK

Firebase Logout On Batch Push

I am creating an app on Android that uses Firebase as database and Batch for pushing notifications. Usually, when my app starts, it goes to the main page, a login activity. The activity verifies if a user is still logged in using:
Firebase dbRef = new Firebase(Constants.URL_DB);
AuthData auth = dbRef.getAuth();
if (auth != null) // Proceed with a logged in user
else // Show authentication layout
My problem is that when I get a notification from Batch, I click on the notification to go to the app but then I am not logged in as I should be... auth == null. I don't want my users to need to log in every time they get a push from Batch. Can I detect that the app started from a notification? How is that I lose authentication from Firebase?
Here is the onCreate and onResume of the MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initiating Batch
Batch.onStart(this);
// Initiating layout
setContentView(R.layout.login);
// Setting database
Firebase.setAndroidContext(this);
// Unrelated stuff done here (Setting Views, etc)
}
#Override
protected void onResume() {
super.onResume();
// Getting login information from previous authentication.
Firebase dbRef = new Firebase(Constants.URL_DB);
AuthData auth = dbRef.getAuth();
// I added the addAuthStateListener here
if (auth != null) {
goToHomePage();
}
}
All right I found the problem. When I click on the notification, my MainActivity is called obviously. The thing is that when the user is logged in successfully, I start another Activity using:
startActivityForResult(intent, Constants.SUCCESS);
Now, onActivityResult is normally called to log out the user when the back button has been pressed on the home page. Otherwise, onResume is called and since the user is logged in, I would go straight back to the home page. BUT: when I click on a notification, somehow onActivityResult is called (probably because the activity stack gets trashed) and the user is logged out before resuming the activity.
So the solution is to log out the user in the onBackPressed of the home page activity. Then I don't need to startActivityForResult anymore.
// In the home page activity
#Override
public void onBackPressed() {
super.onBackPressed();
Firebase dbRef = new Firebase(Constants.URL_DB);
dbRef.unauth();
finish();
}

Android Facebook LoginButton Callback jumps to canceled

I have the following code. It is a simple test of the callback function of the LoginButton in Facebook's Android API.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
setContentView(R.layout.activity_main);
callbackManager = CallbackManager.Factory.create();
LoginButton loginButton = (LoginButton)findViewById(R.id.login_button);
loginButton.setReadPermissions("user_friends");
loginButton.setReadPermissions("email");
loginButton.setReadPermissions("public_profile");
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.e("SUCCESS", "LOGIN SUCCESSFUL");
}
#Override
public void onCancel() {
Log.e("CANCEL", "Cancelled");
}
#Override
public void onError(FacebookException e) {
Log.e("ERROR", "Facebook Exception");
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
The only problem is that whenever I click the loginButton, a dialog appears and disappears for a brief moment, and then the logcat prints out the "CANCEL" text. I cannot seem to fix this error, and I'm not clicking cancel, because that dialog simply shows up and immediately disappears.
Please help me fix this?
As Facebook now requires review of applications which use publish access, you need to log into Facebook Developers Console, in Apps section select your app, click on Roles and add tester (or admin) role.
After this you should be able to get proper access token.
This answer helped me in similar situation.
https://stackoverflow.com/a/31625256/1987045
Call LoginManager.getInstance().logOut(); before attempting a sign in.
I encountered this issue.
It seems to be the case that if you attempt to login (using logInWithReadPermissions or logInWithPublishPermissions) when you already have an access token (with all of the required permissions) then the onCancel callback is executed.
That is to say you should not be logging the user in because the user is already logged in. Check for this first.
My solution:
I had the same problem. The callback was always received by onCancel() method.
I was performing a native login (meaning I was using Facebook App), so after talking with a work-mate, I unistalled my Facebook App to check whether a non-native loging was possible and run my app. To my surprise, before receiving the callback on the onCancel() method, a message informed me my Facebook App ID was wrong, so that was all. I had copied a wrong one instead of the one you get from https://developers.facebook.com/apps.
Now it works and even displays the permissions dialog. What I mean with this is that always try native and non-native. Maybe you get the answer from any of them.
For me this happened because I was calling finish() on my Activity before the Facebook callbacks could complete, causing the activity to finish with RESULT_CANCELED instead of RESULT_OK.
More specifically, my buggy code looked something like this:
#Override
protected void onStart() {
super.onStart();
if (!mAuthRequested) {
mAuthRequested = true;
promptSignIn();
} else {
finish();
}
}
What was happening is that once Facebook's auth activity finishes, onStart() gets called again, but else { finish(); } is invoked before any of Facebook's callbacks are. The fix was to remove the else block.
I hope this helps someone!

Android Facebook SDK: Check if the user is logged in or not

I'm have a feature on my Android app where the user authorizes the app and shares a link.
I also need to give an option for the user to logout of facebook and I need to conditionally disable this button if the user is not logged int (or not authorized the app).
I can't seem to find the API call on the Android SDK that would let me ask FB if the user is logged in or not.
What I have found is getAccessExpires():
Retrieve the current session's expiration time (in milliseconds since
Unix epoch), or 0 if the session doesn't expire or doesn't exist.
Will checking if the session equals 0 be the way to go? Or is there something I'm missing?
Facebook SDK 4.x versions have a different method now:
boolean loggedIn = AccessToken.getCurrentAccessToken() != null;
or
by using functions
boolean loggedIn;
//...
loggedIn = isFacebookLoggedIn();
//...
public boolean isFacebookLoggedIn(){
return AccessToken.getCurrentAccessToken() != null;
}
Check this link for better reference https://developers.facebook.com/docs/facebook-login/android
check this heading too "Access Tokens and Profiles" it says "You can see if a person is already logged in by checking AccessToken.getCurrentAccessToken() and Profile.getCurrentProfile()
I struggled to find a simple answer to this in the FB docs. Using the Facebook SDK version 3.0 I think there are two ways to check if a user is logged in.
1) Use Session.isOpened()
To use this method you need to retrieve the active session with getActiveSession() and then (here's the confusing part) decipher if the session is in a state where the user is logged in or not. I think the only thing that matters for a logged in user is if the session isOpened(). So if the session is not null and it is open then the user is logged in. In all other cases the user is logged out (keep in mind Session can have states other than opened and closed).
public boolean isLoggedIn() {
Session session = Session.getActiveSession();
return (session != null && session.isOpened());
}
There's another way to write this function, detailed in this answer, but I'm not sure which approach is more clear or "best practice".
2) Constantly monitor status changes with Session.StatusCallback and UiLifecycleHelper
If you follow this tutorial you'll setup the UiLifecycleHelper and register a Session.StatusCallback object with it upon instantiation. There's a callback method, call(), which you override in Session.StatusCallback which will supposedly be called anytime the user logs in/out. Within that method maybe you can keep track of whether the user is logged in or not. Maybe something like this:
private boolean isLoggedIn = false; // by default assume not logged in
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (state.isOpened()) { //note: I think session.isOpened() is the same
isLoggedIn = true;
} else if (state.isClosed()) {
isLoggedIn = false;
}
}
};
public boolean isLoggedIn() {
return isLoggedIn;
}
I think method 1 is simpler and probably the better choice.
As a side note can anyone shed light on why the tutorial likes to call state.isOpened() instead of session.isOpened() since both seem to be interchangeable (session.isOpened() seems to just call through to the state version anyway).
Note to readers: This is now deprecated in the new FB 3.0 SDK.
facebook.isSessionValid() returns true if user is logged in, false if not.
Session.getActiveSession().isOpened()
returns true if user is logged in, false if not
Android Studio with :
compile 'com.facebook.android:facebook-android-sdk:4.0.1'
then check login like as:
private void facebookPost() {
//check login
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken == null) {
Log.d(TAG, ">>>" + "Signed Out");
} else {
Log.d(TAG, ">>>" + "Signed In");
}
}
#diljeet was right. https://stackoverflow.com/a/29375963/859330
In addition, use
return AccessToken.getAccessToken() != null && Profile.getCurrentProfile()!=null;
It always works this way.
For Facebook Android SDK 4.x you have to use the "AccessToken.getCurrentAccessToken()" as said by #Diljeet but his check didn't work for me, I finally checked it by doing:
Activity "onCreate":
facebookAccessToken = AccessToken.getCurrentAccessToken();
To check if the session is still active (I made it in the "onResume" method but do it where you need):
if(facebookAccessToken != null){
sessionExpired = facebookAccessToken.isExpired();
}else{
sessionExpired = true;
}
More info in https://developers.facebook.com/docs/facebook-login/android
This seems to be working quite well with the new sdk.
private boolean isFacebookLoggedIn(){
Session session = Session.getActiveSession();
if (session != null) {
//Session can be open, check for valid token
if (!session.isClosed()) {
if(!session.getAccessToken().equalsIgnoreCase("")){
return true;
}
}
}
return false;
}
I had the same issue. Here is my solution using SDK 4.0:
First of all, in your activity dealing with login check, be sure to call this primary:
FacebookSdk.sdkInitialize(this.getApplicationContext());
In your onCreate method put this :
updateWithToken(AccessToken.getCurrentAccessToken());
new AccessTokenTracker() {
#Override
protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken newAccessToken) {
updateWithToken(newAccessToken, handler);
}
};
Then add the method called:
private void updateWithToken(AccessToken currentAccessToken) {
if (currentAccessToken != null) {
fillUIWithFacebookInfos(handler);
} else {
login();
}
}
This way will handle the already logged in user and the newly logged in user.
I was using FB sdk for just for login..
Facebook developers reject my app, Because whenever user login, I send logout.. I dont matter user profile data... I just use FB for login.. FB tells if user login... dont send lgout...
I find Hacking way...
Now my app doesnot send logout whenever user login.... Whatever user login with,Google,Facebook,or normal.. When they click logout... In this three condition
I use
LoginManager.getInstance().logOut();
No matter which platform they use... There is no crash :)

How can I switch authorized facebook user with Facebook Android SDK?

I have successfully implemented authorization with facebook in my native android app.
Now I have following problem:
User logout from my app and I call facebook sdk logout method. But when user presses login button it automatically redirects back to my app without showing "Already authorized" window, so he cannot switch to another user.
Is that normal behavior or I've made something wrong? How can I solve this issue?
If you would like to switch to another user, you can refer to the "SwitchUserSample" in Facebook SDK for Android.
Here is some example code fyi.
Session currentSession = Session.getActiveSession();
currentSession.closeAndClearTokenInformation();
newSession = new Session.Builder(LoginActivity.this).build();
newSession.openForRead(new Session.OpenRequest(LoginActivity.this)
.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO)
.setCallback(statusCallback));
No that's not default we can switch user. While you are doing Logout you are not clearing credentials properly so such problems arise , so you need to remove credentials perfectly.
You should got through the HackBook code given by Facebook for all features , where you have to save you Facebook object in SessionStore class and handle it accordingly :
private class SessionListener implements AuthListener, LogoutListener {
#Override
public void onAuthSucceed() {
setImageResource(R.drawable.logout_button);
SessionStore.save(mFb, getContext());
}
#Override
public void onAuthFail(String error) {
}
#Override
public void onLogoutBegin() {
}
#Override
public void onLogoutFinish() {
SessionStore.clear(getContext());
setImageResource(R.drawable.login_button);
}
}

Categories

Resources