Updating facebook android session permissions without logging out and in again - android

I am using the Facebook SDK for an Android app which requires 2 permissions additional to the standard one for logging in/out.
The two permissions are a read permission: User Groups and a publish permissions: publish.
The problem is that in the latest facebook api requires to ask each permission separately. Which I am fine with.
The issue is that the session object is not updated with the new permissions after the user confirms them, unless I logout and login into the app again.
This would not be an issue if I could ask all permissions at once, but again, not possible anymore.
Is there any other way to avoid this?
And yes, I have tried everything in the OnActivityResult, and the permissions in the Session.getActiveSession() object is not updated with the new permissions, even though if I try to do the needed action it works.
And it's totally unfeasable to ask the user to logout and login of the app after each permission request.
This is what I have in my OnActivityResult (which works completely fine btw).
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("RADARE","ON ACTIVITY RESULT CALLED");
Log.d("RADARE","REQUEST CODE: " + requestCode + " == RESULT CODE: " + resultCode + " == INTENT: " + data.toString());
if (RESULT_CANCELED == resultCode) {
Log.d("RADARE", "Canceled");
}
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data, new FacebookDialog.Callback() {
#Override
public void onError(FacebookDialog.PendingCall pendingCall, Exception error, Bundle data) {
Log.e("Activity", String.format("Error: %s", error.toString()));
}
#Override
public void onComplete(FacebookDialog.PendingCall pendingCall, Bundle data) {
Log.i("Activity", "Success!");
}
});
Session session = Session.getActiveSession();
Log.d("RADARE","Session info: TOKEN: " + session.getAccessToken() + " == PERMISSIONS: " + session.getPermissions().toString() + " == STATE: " + session.getState());
Toast.makeText(this, "You have to logout and login again in order for the service to work.", Toast.LENGTH_LONG).show();
My first idea would be instead of using Session.getPermissions().contains("needed_permission_here") to actually check online for the permission instead of the Session object.
Right now it just enters a loop:
The permissions are checked => permissions is not there => Jumps to facebook app asking for permissions => the user grants it => the app checks again for permission (which are not there even though the user has confirmed them) and jumps to facebook (which of course just replies back with the confirmed permission) and they dance back and forth infinitely.
Do you have any other ideas than checking the permissions online instead of the object?

Quoting from FB Login Permissions page
user_groups- Limited Use
This permission is granted to apps building a Facebook-branded client on platforms where Facebook is not already available. For example, Android and iOS apps will not be approved for this permission. In addition, Web, Desktop and TV apps will not be granted this permission
And for checking if the permissions are granted already
private static final String PERMISSION = "publish_actions";
<- Whatever read permissions you need ->
authButton.setReadPermissions(Arrays.asList("email", "user_birthday",
"read_stream", "user_friends","read_friendlists "));
public void call(Session session, SessionState state,
Exception exception) {
if (session.isOpened()) {
List<String> permissions = session.getPermissions();
if (!permissions.contains(PERMISSION)) {
pendingAnnounce = true;
requestPublishPermissions(session);
return;
}
}
I dont know how much of help this will be to you..

Related

FacebookSDK Request.newMeRequest onCompleted called on JELLYBEAN but not KITKAT or LOLLIPOP

This code results in the onCompleted method being called on Samsung JELLYBEAN but not on Motorola KITKAT or LG LOLLIPOP devices. The log returns: W/Facebook test(20699): Facebook session status changed - OPENED - Exception: null on all devices.
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state, Exception exception) {
String message = "Facebook session status changed - "
+ session.getState() + " - Exception: " + exception;
Log.w("Facebook test", message);
if (session.isOpened()) {
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
Log.d("onCompleted","");
}
}).executeAsync();
}
}
}
I have checked permissions and the hashes stored. This is my onActivityResult method:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
UPDATE: I created a test project with identical code to the problem app. This project doesn't have the problem, which suggests it isn't a java issue. The manifests are the same with regards to Facebook. I have the correct app_id in each case. The settings of the apps on developers.facebook.com are the same except for package name, class name and key hash.
Go to developers.facebook.com
Select your app
Select Status and Review
Change "Do you want to make this app and all its live features
available to the general public?" to NO
(I waited about ten minutes at this point, which may not be necessary)
Then change the same setting back to YES

Getting Empty user after Facebook login in ParseAndroid

I am using Parse Android SDK for my application
I am using the following code for Facebook login
Even it is the new user or old user, Else block is always executed. All I am getting is Empty User (object id is null).
I did following checklist
1. I wiped out all data from my backend
2. I created new Facebook Application with bebug Hash Key
3. I used the same Facebok Application ID in my code
4. I ensured whether the debuggable=true is set in Androidmanifest
Can anyone help in this ?
ParseFacebookUtils.logIn(Arrays.asList(Constants.EMAIL, Permissions.Friends.ABOUT_ME), activity, new LogInCallback()
{
#Override
public void done(ParseUser user, ParseException err)
{
if(err!=null)
{
err.printStackTrace();
}
if (user == null)
{
errorClosure.callback(null);
}
else if (user.isNew())
{
Log.e("user.isNew", user.getObjectId()+"");
//ParseFacebookUtils.link(user, Arrays.asList(Constants.EMAIL, Permissions.Friends.ABOUT_ME),activity, new OnParseUserSaveCallBack(user, successClosure));
}
else
{
Log.e("Object IDDDDDDDDD", user.getObjectId()+"");
successClosure.callback(null);
}
}
});
ParseUser with null values after a Facebook login is currently a bug of the Parse SDK >= 1.5.0. See here: https://developers.facebook.com/bugs/229876443869758/
Do you have the Local Datastore enabled, too? A workaround is to disable it, until an official fix is released.
EDIT: Also, have you checked if ParseFacebookUtils.finishAuthentication() is called on the Activity? In other words, you should ovverride the onActivityResult() method this way:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
ParseFacebookUtils.finishAuthentication(requestCode, resultCode, data);
}
Getting this error consistently on Android 4.2. I found one workaround but it's only works for API 19+ as part of my signout I call ActivityManager.clearApplicationUserData() which purges the local file(s) that are causing the parse SDK issue. Now the user can now sign in again with facebook fine.
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){
logger.debug("yay we're on 19+ clearApplicationUserData");
ActivityManager am = (ActivityManager)CMeApp.get().getSystemService(Context.ACTIVITY_SERVICE);
am.clearApplicationUserData();
}

AccessToken token:ACCESS_TOKEN_REMOVED in Facebook Android SDK

I am using the Facebook SDK but I want to create the photo album but I am getting ACCESS_TOKEN_REMOVED in the session.
Getting this in session
{Session state:OPENED, token:{AccessToken token:ACCESS_TOKEN_REMOVED permissions:[read_stream, manage_friendlists, read_mailbox, status_update, photo_upload, video_upload, sms, create_event, rsvp_event, email, xmpp_login, create_note, share_item, publish_stream, ads_management, read_insights, read_requests, manage_notifications, read_friendlists, manage_pages, publish_actions, user_birthday, user_religion_politics, user_relationships, user_relationship_details, user_hometown, user_location, user_likes, user_activities, user_interests, user_education_history, user_work_history, user_online_presence, user_website, user_groups, user_events, user_photos, user_videos, user_photo_video_tags, user_notes, user_checkins, user_about_me, user_status, basic_info]}, appId:458921577539675}
Code.
/**
* Connect to facebook using Facebook SDK.
*/
public void connectToFacebook() {
Session session = Session.getActiveSession();
if(session == null || session.isClosed()) {
Session.openActiveSession((Activity)context, true, new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if(session.isOpened() && state == SessionState.CREATED_TOKEN_LOADED) {
Log.v(GlobalVars.TAG, "Token::" + session.getAccessToken());
Request.executeMeRequestAsync(session, new GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if(response != null) {
Log.v(GlobalVars.TAG, "Response::" + response);
Log.v(GlobalVars.TAG, "Response::" + user.getFirstName() + ":::" + user.getLastName());
}
}
});
}
}
});
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
If you are just seeing ACCESS_TOKEN_REMOVED in your log, make sure you are printing session.getAccessToken().getToken(). In the example above, replace
Log.v(GlobalVars.TAG, "Token::" + session.getAccessToken());
with
Log.v(GlobalVars.TAG, "Token::" + session.getAccessToken().getToken());
Same problem that i was facing from last 2 days and finally i get to know this. Facebook SDK will not log access tokens to logcat (to avoid leaking user tokens via the log as said in decsription).
Just add these lines after FacebookSdk.sdkInitialize(), i would recomend you do this only in debug mode:
if (BuildConfig.DEBUG) {
FacebookSdk.setIsDebugEnabled(true);
FacebookSdk.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
}
You have to enable facebook sign in on Firebase Console and add the facebook app id and app secret key and it should work fine
I took the same problem :/
You can check:
Is appId correct?
Was keyhash registered in facebook app center?
Does app namespace / package name match with your manifest file? ( on facebook app center )
Is application live?
If everything is right I really don't know how to help you...
I checked all items that Fernando said and add it
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
I don't know if this last line was what solved the problem or if it's something random.
I'm using Facebook Android SDK 3.17 for Xamarin
Greetings from Argentina
Hernan
www.hernanzaldivar.com

Login with extra permission with Facebook SDK 3 for Android

I followed the step of "Create a new Android Project with Facebook Login" section at https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/ The login process is fine. Because I would like to use the native Android button for a user to log in, I modify the code slightly by moving the following code into a View.OnClickListener() of a native Android button. The following is the code in the listener:
Session.openActiveSession(MainActivity.this, true, new 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) {
Toast.makeText(getApplicationContext(), "Hello " + user.getName() +" "+user.getId()+"!", Toast.LENGTH_LONG).show();
}
}
});
}
}
});
The onActivityResult() and AndroidManifest.xml is the same as the tutorial
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
However, I would like to request get "read_friendlists" when a user logs in successfully. I read the tutorial at https://developers.facebook.com/docs/tutorials/androidsdk/3.0/scrumptious/authenticate/ but it uses Facebook SDK customized button. How can I achieve the same behavior with a native Android button like my code shown above?
I just answered a similar question on another post. My solution allows you to use a native button and request additional read permissions when the user first logs in. Check it out here Ask for more permissions with 3.0 SDK

Android - facebook sdk Login window disappear

I am trying to use the Android Facebook SDK - but with no luck.
The problem is that the Facebook Login window starts loading, but before anything happens it disappears. This is the behaviour on an actual device, on the emulator all is good.
What I have done:
downloaded the SDk from here
added the java files to my project.
created a facebook application.
Got the Key Hash value and updated my facebook app.
But I cant get the Login window to appear. I dont see any error on the logcat, only this:
ActivityManager( 2698): Starting: Intent { cmp=com.facebook.katana/.ProxyAuth (has extras)
ActivityManager( 2698): Trying to launch com.facebook.katana/.ProxyAuth
ActivityManager( 2698): Displayed com.facebook.katana/.ProxyAuth: +371ms (total +466ms)
Any ideas?
10X :)
EDIT:
It seems adding these lines of code to the activity solved the problem:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
Got if from here: SO Question
That logcat error from com.facebook.katana is from the Android Facebook app. Is that installed on the phone? It sounds like it is and you are defaulting to Single Sign On (SSO)?
Try doing your authorize as
authorize(this, PERMISSIONS, FORCE_DIALOG_AUTH, new LoginDialogListener());
which avoids SSO and forces a dialog login.
If that circumvents your crash, then the most likely cause is a mismatch between the SDK and the installed Facebook app. They do tend to be quite picky about working together. If so, you'll probably have to try several different versions of each before you find a stable pair.
Do you already install on device native application facebook? Because com.facebook.katana - this is from facebook application. It could happen, because already auth by this application.
What I do?
I comments in facebook.java code:
public void authorize(Activity activity, String[] permissions, int activityCode, final DialogListener listener) {
boolean singleSignOnStarted = false;
mAuthDialogListener = listener;
// Prefer single sign-on, where available.
// if (activityCode >= 0) {
// singleSignOnStarted = startSingleSignOn(activity, mAppId, permissions, activityCode);
// }
// Otherwise fall back to traditional dialog.
if (!singleSignOnStarted) {
startDialogAuth(activity, permissions);
}
}
Also I try do multi login and find problem, when I auth with one login/password, try add new login, show facebook dialog and in browser auto page login show and immediately disappears. Because occurred login with previos data. When I in facebook.java:
disable in startDialogAuth cookies.
private void startDialogAuth(Activity activity, String[] permissions) {
Bundle params = new Bundle();
if (permissions.length > 0) {
params.putString("scope", TextUtils.join(",", permissions));
}
// CookieSyncManager.createInstance(activity);
Util.clearCookies(activity);
dialog(activity, LOGIN, params, new DialogListener() {
public void onComplete(Bundle values) {
// ensure any cookies set by the dialog are saved
// CookieSyncManager.getInstance().sync();
setAccessToken(values.getString(TOKEN));
setAccessExpiresIn(values.getString(EXPIRES));
if (isSessionValid()) {
Tracks.itTrack(Tracks.Dev, "Facebook-authorize. Login Success! access_token=%s expires=%s", getAccessToken(), getAccessExpires());
mAuthDialogListener.onComplete(values);
}
else
mAuthDialogListener.onFacebookError(new FacebookError("Failed to receive access token."));
}
public void onError(DialogError error) {
Tracks.itTrack(Tracks.Dev, "Facebook-authorize. Login failed: %s", error);
mAuthDialogListener.onError(error);
}
public void onFacebookError(FacebookError error) {
Tracks.itTrack(Tracks.Dev, "Facebook-authorize. Login failed: %s", error);
mAuthDialogListener.onFacebookError(error);
}
public void onCancel() {
Tracks.itTrack(Tracks.Dev, "Facebook-authorize. Login canceled");
mAuthDialogListener.onCancel();
}
});
}
You might want put some debug messages (log.v()) in each of the Facebook Dialog events (onComplete, onFacebookError, onError, onCancel). I had the same problem; though, my problem was related to the key hash, I had the incorrect keyhash. If the keytool doesn't ask you for a password, it gives you the incorrect key. With the incorrect keyhash, I got the same behavior as you.
Another thing might be that you are already logged onto Facebook in your device. Therefore, it doesn't need to ask for your permission. If that's the case, log out of Facebook, then run your application.

Categories

Resources