I've encountered a problem. During login I ask read permissions, that seems to work fine, but whenever I want to share something I use this method to check for required permissions:
public interface OnWritePermissionListener {
public void result(boolean success);
}
public void askWritePermissions(final OnWritePermissionListener listener) {
if (!getSession().getPermissions().containsAll(writePermissions)) {
L.d("Requesting write permissions.");
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(activity, writePermissions);
newPermissionsRequest.setCallback(new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
L.d("Status callback for askWritePermissions. State: %s. Exception: %s.", state.name(), exception == null ? "none" : exception.toString());
if (session.getPermissions().containsAll(writePermissions)) {
listener.result(true);
} else {
listener.result(false);
}
}
});
getSession().requestNewPublishPermissions(newPermissionsRequest);
} else {
L.d("Write permissions already granted.");
listener.result(true);
}
return;
}
writePermissions contains string entry: "publish_actions"
The problem is that when I call this method the FB window appears only for a half second and then dissapears calling listener.result(false). Log shows this:
Status callback for askWritePermissions. State: OPENED_TOKEN_UPDATED. Exception: none.
Any ideas what I might be doing wrong?
Related
I've set up a user pool for a mobile application. The sign up process works as expected, however, attempting to log in the user in results in the following Exception:
User login alias should not be null (Service:
AmazonCognitoIdentityProvider; Status Code: 400; Error Code:
InvalidParameterException; Request ID: xxx....)
This error is being produced during the sign in attempt, called via:
CognitoUserPool.getUser(username).getSessionInBackground(authenticationHandler);
To provide a fuller snippet of the code, when the user clicks the login button, a function containing the following code is run:
AuthenticationHandler authenticationHandler = new AuthenticationHandler() {
#Override
public void onSuccess(CognitoUserSession userSession) {
Util.showMessage(mContext, "User Successfully Signed In. Session JWT Token: " + userSession.getIdToken().getJWTToken());
btnLogin.setProgress(100);
}
#Override
public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String UserId) {
AuthenticationDetails authenticationDetails = new AuthenticationDetails(UserId, edtPassword.getText().toString().trim(), null);
authenticationContinuation.setAuthenticationDetails(authenticationDetails);
authenticationContinuation.continueTask();
}
#Override
public void getMFACode(MultiFactorAuthenticationContinuation continuation) {
Util.showMessage(mContext, "MFA Code is Required");
// Set Up MFA Process
}
#Override
public void onFailure(Exception exception) {
Log.d(TAG, exception.toString());
Snackbar.make(edtUsername, exception.getMessage(), Snackbar.LENGTH_LONG).show();
btnLogin.setProgress(-1);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
setUpLoginClick();
}
}, 1000);
}
};
AWS.userPool(mContext).getUser(edtUsername.getText().toString()).getSessionInBackground(authenticationHandler);
AWS.userPool(Context ctx) is a utility function that i wrote to quickly retrieve the configured UserPool object.
Can anyone shed some light on why this might be happening? I can't find discussion or documentation of this error anywhere.
I have a big problem with android-facebook-sdk 3.19.1. No problem to retrieve public information about user but it is not possible getting email address.
I know my post is very near to the following thread ==> facebook android sdk -user email returns null but I have no solution for now.
So here is my code
In my ConnectionActivity.java I have a button R.id.fb_connect
private List<String> permissions = Arrays.asList("email");
#Click(R.id.fb_connect)
protected void fbConnect() {
ensureOpenSession();
}
private boolean ensureOpenSession() {
Session session = Session.getActiveSession();
if (session == null || !session.isOpened()) {
LOGD(TAG, "Call Session.openActiveSession");
Session.openActiveSession(this, true, permissions, new FbCallback());
return false;
}
return true;
}
public class FbCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState sessionState, Exception e) {
// make request to the /me API
Request.newMeRequest(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
// user.asMap().get("email");
Toast.makeText(ConnectionActivity.this, "email : " + user.getProperty("email"), Toast.LENGTH_LONG).show();
}
}
}).executeAsync();
}
}
I've also tried the code in the link above but it doesn't work. One precision, with this code, I can see the facebook activity which says "XXX will receive the following info: your public profile and email address" but the toast displays "email : null"
EDIT
I work with android studio and my gradle file has the following line
compile 'com.facebook.android:facebook-android-sdk:3.19.1'
EDIT2
If I use
LOGD(TAG, "isPermissionGranted : " + session.isPermissionGranted(permissions.get(0)));
before call Request.newMeRequest so true is shown. Permission is correctly granted
Thx
Login and asking permission works just fine. But there is one problem: I need to ask publish permission when user wants to share some date from my app. Here is my code:
ParseFacebookUtils.getSession().requestNewPublishPermissions(new NewPermissionsRequest((Activity) context,
Arrays.asList(Permissions.Extended.PUBLISH_ACTIONS, Permissions.Extended.PUBLISH_STREAM))
.setCallback(new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (!arePublishPermissionsEnabled(session)) {
inflow.setChecked(false);
facebook.setChecked(false);
twitter.setChecked(false);
}
}
}));
The problem is in handling situation when user canceled request or there is a loss of network connection. In this case I need to do some changes in my UI, but method call is calling only when session state is changed (e.g. granted new permissions) and I can't properly changed my UI. Is anyone faced such problem?
private void requestPublishPermissions(Session session) {
List<String> PERMISSIONS = Arrays.asList("publish_actions", "publish_stream");
if (session != null) {
pendingAnnounce = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(this, PERMISSIONS);
newPermissionsRequest.setRequestCode(REAUTH_ACTIVITY_CODE);
Session mSession = Session.openActiveSessionFromCache(this);
mSession.addCallback(callback);
mSession.requestNewPublishPermissions(newPermissionsRequest);
}
}
I'm developing an Android application, and I'm using this code to get some data from Facebook:
public void onFBLoginClick(View view)
{
// start Facebook Login
Session.openActiveSession(this, true, new Session.StatusCallback()
{
// callback when session changes state
#Override
public void call(final 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)
{
txtUserName.setText(session.getAccessToken());
saveUserData(user.getId(), user.getName(), user.getBirthday(), user.asMap().get("email").toString());
saveAccessToken(session.getAccessToken());
getFacebookUserProfilePicture(session.getAccessToken());
}
}
});
}
}
});
}
But, I can't get the email. Always is null.
I set up email permissions on User & Friend Permissions, on developers.facebook.com, but it doesn't work.
What am I doing wrong?
Use this code to open your session and you are ready to go!
String[] PERMISSION_ARRAY_READ = {"email","user_birthday"};
List<String> PERMISSION_LIST=Arrays.asList(PERMISSION_ARRAY_READ);
session.openForRead(new Session.OpenRequest(getParent()).setPermissions(PERMISSION_LIST).setCallback(statusCallback));
let me know if uyou have any problem regarding this.
I am developing an Android App that integrates with Facebook. I would like to:
Let the user login with Facebook
Get the user's email address on Facebook (could be a proxied email address, which is fine)
Post to the user's wall/timeline on his/her behalf
Technically, that would be to:
Authenticate the user
Request the email permission
Request the publish_stream permission
1. Authenticate the user
I called Session.openActiveSession() with a Session.StatusCallback (I already checked that there is no active opened session beforehand):
final Session.StatusCallback sessionStatusCallback = new Session.StatusCallback() {
public void call(final Session session, SessionState state, Exception exception) {
// If there is an exception...
if(exception != null)
{
// Handle fail case here.
return;
}
// If session is just opened...
if(state == SessionState.OPENED)
{
// Handle success case here.
return;
}
};
};
// Start Facebook Login.
Session.openActiveSession(activity, true, sessionStatusCallback);
My callback is called after successful login. So far so good.
2. Request the email permission
This is my status callback:
new Session.StatusCallback() {
public void call(final Session session, SessionState state, Exception exception) {
// If there is an exception...
if(exception != null)
{
// Handle fail case here.
return;
}
// If token is just updated...
if(state == SessionState.OPENED_TOKEN_UPDATED)
{
// Handle success case here.
return;
}
};
};
I request the permission with Session.requestNewReadPermissions():
final Session session = Session.getActiveSession();
final static String[] PERMISSION_ARRAY_READ = {"email"};
final List<String> permissionList = Arrays.asList(PERMISSION_ARRAY_READ);
// If all required permissions are available...
if(session.getPermissions().containsAll(permissionList))
{
// Handle success case here.
return;
}
// Request permissions.
session.requestNewReadPermissions(new Session.NewPermissionsRequest(activity, permissionList));
My callback is called after permission is granted. So far so good.
3. Request the publish_stream permission
This is my status callback:
new Session.StatusCallback() {
public void call(final Session session, SessionState state, Exception exception) {
// If there is an exception...
if(exception != null)
{
// Handle fail case here.
return;
}
// If token is just updated...
if(state == SessionState.OPENED_TOKEN_UPDATED)
{
// Handle success case here.
return;
}
};
};
I request the permission with Session.requestNewPublishPermissions():
final Session session = Session.getActiveSession();
final static String[] PERMISSION_ARRAY_PUBLISH = {"publish_stream"};
final List<String> permissionList = Arrays.asList(PERMISSION_ARRAY_PUBLISH);
// If all required permissions are available...
if(session.getPermissions().containsAll(permissionList))
{
// Handle success case here.
return;
}
// Request permissions.
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(activity, permissionList));
This time, my callback is not called after permission is granted.
Investigation
Upon further investigation, I found that my callback is triggered by com.facebook.Session#postStateChange(SessionState, SessionState, Exception):
void postStateChange(final SessionState oldState, final SessionState newState, final Exception exception) {
if (oldState == newState && exception == null) {
return;
}
/* ... */
}
Since oldState and newState are equal (both being SessionState.OPENED_TOKEN_UPDATED, my callback is not called.
Question
How can I receive any notification after permission is granted for the 2nd time? Am I supposed to close() the session and re-open it from cache?
Additional info
My Facebook Android SDK 3.0 is download from here, which is stated in Facebook's Getting Started with the Facebook SDK for Android.
This is a bug.
[edit: As Guy points out in comments, this was fixed in 3.0.1, so this workaround is no longer necessary]
The workaround you mention is basically correct, though you do not need to call close. If you are using the single active session, before calling requestNewPublishPermissions() just call:
Session.openActiveSessionFromCache(myContext);
If you are using multiple sessions, you need to initialize a new Session with the TokenCachingStrategy, verify it is in the CREATED_TOKEN_LOADED state, and call openForRead(null);
After doing one of these, requestNewPublishPermissions() should call your notification once it completes.
Working code based on rightparen's answer
Before requesting permission for the 2nd time (i.e. before Session.requestNewPublishPermissions()), do this:
// Re-initialize Facebook session.
session.removeCallback(sessionStatusCallback); // Remove callback from old session.
session = Session.openActiveSessionFromCache(context); // Create new session by re-opening from cache.
session.addCallback(sessionStatusCallback); // Add callback to new session.
Code is still based on Facebook Android SDK 3.0, as in the question.
Another thing I ran into was that my requestCode for the NewPermissionRequest was not being set to the same requestCode that I used to open my Session for Read with, thereby my Session.StatusCallback was never being invoked when the new permissions have been granted.
For instance, in my onActivityResult I have a check for the requestCode and delegate the call accordingly because I have other stuff coming in to this method.
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
if (requestCode == FACEBOOK_AUTH_RESULT_CODE) {
Session session = Session.getActiveSession();
if(session != null) {
session.onActivityResult(activity, requestCode, resultCode, data);
}
}
}
I then opened my Session with the following code :
Session.getActiveSession().openForRead(
new Session.OpenRequest(activity).
setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK).
setRequestCode(FACEBOOK_AUTH_RESULT_CODE).
setPermissions(MY_READ_PERMISSIONS));
I then forgot to use the same requestCode when constructing my NewPermissionRequest.
This is what the correct NewPermissionRequest needs to look like :
Session.getActiveSession().requestNewPublishPermissions(
new NewPermissionsRequest(activity, MY_PUBLISH_PERMISSIONS)
.setRequestCode(FACEBOOK_AUTH_RESULT_CODE));