Unable to get Publish Permission With Test User Facebook Android - android

I want to publish post to user's wall. I know Facebook only allows tester and developers to post on wall. I have already added user to tester list. When I try to get publish permission, it says that user has already granted permission (as shown in screenshot) and returns. I am not able to get permission or post on wall. Moreover, callback's any method is not called as well.
CODE
I have followed code from Facebook Example RPSSample.
//Publish to wall
public void publishResult() {
registerPublishPermissionCallback();
if (canPublish()) { //see definition below
ShareLinkContent content = new ShareLinkContent.Builder()
.setContentUrl(Uri.parse(urlToPost))
.build();
ShareApi.share(content, new FacebookCallback<Sharer.Result>() {
#Override
public void onSuccess(Sharer.Result result) {
callback.didShareOnFacebookSuccessfully();
}
#Override
public void onCancel() {
// This should not happen
}
#Override
public void onError(FacebookException error) {
showToast(error.getMessage());
}
});
}
}
//check if user has permission or not
private boolean canPublish() {
final AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken != null) {
if (accessToken.getPermissions().contains(AppConstants.ADDITIONAL_PERMISSIONS)) {
// if we already have publish permissions, then go ahead and publish
return true;
} else {
// otherwise we ask the user if they'd like to publish to facebook
new AlertDialog.Builder(activity)
.setTitle(R.string.share_with_friends_title)
.setMessage(urlToPost)
.setPositiveButton(R.string.share_with_friends_yes, canPublishClickListener)
.setNegativeButton(R.string.share_with_friends_no, dontPublishClickListener)
.show();
return false;
}
}
return false;
}
//If user allows, ask Facebook to grant publish_action permission
private DialogInterface.OnClickListener canPublishClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if (AccessToken.getCurrentAccessToken() != null) {
// if they choose to publish, then we request for publish permissions
LoginManager.getInstance()
.setDefaultAudience(DefaultAudience.FRIENDS)
.logInWithPublishPermissions(activity,
Arrays.asList(AppConstants.ADDITIONAL_PERMISSIONS));
}
}
};
//Callback - Any of the method doesn't call.
private void registerPublishPermissionCallback() {
LoginManager.getInstance().registerCallback(
callbackManager,
new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken.getPermissions().contains(AppConstants.ADDITIONAL_PERMISSIONS)) {
publishResult();
} else {
handleError("Not enough permissions to publish");
}
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException exception) {
handleError(exception.getMessage());
}
private void handleError(String errorMessage) {
// this means the user did not grant us write permissions, so
// we don't do implicit publishes
showToast(errorMessage);
}
}
);
}
My app is live on console. Please guide what is requirement of Facebook to get publish permission with test user? Thanks.

Use below code to check if permission is Granted or not.
String url = "/" + "(userFbID)" + "/permissions";
new GraphRequest(AccessToken.getCurrentAccessToken(), url, null,
HttpMethod.GET, new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
try {
JSONObject json = new JSONObject(
response.getRawResponse());
JSONArray data = json.getJSONArray("data");
boolean isPermitted = false;
for (int i = 0; i < data.length(); i++) {
if (data.getJSONObject(i)
.getString("permission")
.equals("publish_actions")) {
isPermitted = true;
String status = data.getJSONObject(i)
.getString("status");
if (status.equals("granted")) {
publishResult()
} else {
LoginFacebook();
}
break;
}
}
if (!isPermitted) {
LoginFacebook();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).executeAsync();
replace user's fb id on place of (userFbID).
If permission is not granted then use this function to ask user for that permission.
private void LoginFacebook() {
loginManager = LoginManager.getInstance();
loginManager.logInWithPublishPermissions(this,
Arrays.asList("publish_actions"));
loginManager.registerCallback(callbackManager,
new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
publishResult()
}
#Override
public void onError(FacebookException error) {
}
#Override
public void onCancel() {
}
});
}

Finally able to solve the problem. There was no issue in code. It was some setting / permission issue with Facebook app. These are steps I followed:
Remove the user from Test role section in your Facebook Developer Console.
Revoke App's Access by logging into that user's account. Go to Settings > Apps. Remove the app from there. You need to wait 10-15 min, since it takes time from Facebook side to revoke access completely.
Make your Facebook App in Sandbox mode (you need to do this to perform publish testing).
Login your android app using any Facebook account other than app admin. It should throw error that app is in development mode.
Add user as Tester in the Facebook Console App. That user may need to approve pending request at his side.
Login from that user account. Facebook will now ask you to provide basic information access to the app. After that you can test publishing. You will be able to post on the user's wall successfully.
Hope this helps someone!

Related

How to sign out of aws cognito - android?

So here is the code i used to sign my user into cognito (i hope im correct). Now, how would i sign out? Currently i have my own signing up process (so no facebook or google yet).
// Callback handler for the sign-in process
private AuthenticationHandler authenticationHandler = new AuthenticationHandler()
{
#Override
public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice)
{
Log.d(COGNITO_LOGIN,"Login success!");
cognitoUser.getDetailsInBackground(getDetailsHandler);
//Now we get user from dynamoDB and store it into a local user object.
}
#Override
public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId)
{
Log.d(COGNITO_LOGIN,passwordET.getText().toString());
// The API needs user sign-in credentials to continue
AuthenticationDetails authenticationDetails = new AuthenticationDetails(userId, passwordET.getText().toString(), null);
// Pass the user sign-in credentials to the continuation
authenticationContinuation.setAuthenticationDetails(authenticationDetails);
// Allow the sign-in to continue
authenticationContinuation.continueTask();
}
#Override
public void getMFACode(MultiFactorAuthenticationContinuation multiFactorAuthenticationContinuation) {
// Multi-factor authentication is required; get the verification code from user
multiFactorAuthenticationContinuation.setMfaCode("verificationCode");
// Allow the sign-in process to continue
multiFactorAuthenticationContinuation.continueTask();
}
#Override
public void authenticationChallenge(ChallengeContinuation continuation) {
}
#Override
public void onFailure(Exception exception)
{
// Sign-in failed, check exception for the cause
Log.d(COGNITO_LOGIN,"Login failed!");
Log.d(COGNITO_LOGIN,exception.getMessage());
}
};
cognitoUser.getSessionInBackground(authenticationHandler);
You should be able to just call signOut on a cognitoUser object such as below. What that does is clear access, id and refresh tokens from the device so you would need to authenticate again.
// This has cleared all tokens and this user will have to go through the authentication process to get tokens.
user.signOut();
There is also a globalSignOut call that revokes tokens server-side.
There is a way to wipe or clear the session for the current user who logged, the following is the way, which I found so far.
This is for fb in federated identities
if (fbAccessToken != null) {
LoginManager.getInstance().logOut();
}
This is for twiiter
if (mAuthManager != null) {
mAuthManager.clearAuthorizationState(null);
}
// wipe data
CognitoSyncClientManager.getInstance()
.wipeData();
CognitoUserPool pool = AwsCognitoHelper.getPool();
if (pool != null) {
CognitoUser user = pool.getCurrentUser();
if (user != null) {
GenericHandler handler = new GenericHandler() {
#Override
public void onSuccess() {
}
#Override
public void onFailure(Exception e) {
}
};
user.globalSignOutInBackground(handler);
}
}

How to get User's information after logging in Facebook app and authorized your app? [Android]

I'm using this for my Facebook log-in and sharing. I'm wondering if instead of opening a WebView that displays the log-in with Facebookis there a way when a User have already installed a Facebook app instead of opening the WebView it will opens the Facebook app? And when the User is already log-in in the Facebook App it will gets its credentials and log-in automatically in my app? I can't seem to find how to do this. Thank you in advantage.
Edit
I found out that my activityCode always return -1 instead of >= 0 that's why it always open the WebView instead of the app. And also found out that I need to enabled the Single Sign-On, I enabled the Single Sign-On but it still doesn't open the facebook app. Maybe it is because of FORCE_DIALOG_AUTH that always returns -1. I'm wondering if there is a default value instead of using FORCE_DIALOG_AUTH.
In solution on the FORCE_DIALOG_AUTH I used code below:
Instead of using
facebook.authorize(this, Constants.FACEBOOK_PERMISSIONS,
Facebook.FORCE_DIALOG_AUTH, new LoginDialogListener());
I used
facebook.authorize(this, Constants.FACEBOOK_PERMISSIONS, new LoginDialogListener());
where in my Facebook.java
public void authorize(Activity activity, String[] permissions,
final DialogListener listener) {
authorize(activity, permissions, DEFAULT_AUTH_ACTIVITY_CODE, listener);
}
Also it detects now if there is an Facebook app installed or not, but when there is an Facebook app installed it still doesn't display/open in Facebook app, it just load and goes back to my Activity nothing happens.
Update
I tried to log in without a user log-in in the Facebook app and that user is still not authorized to use my app, it opens the Facebook app log-in screen but after authorizing it, it doesn't get my log-in informations.
Here's my code in Facebook.java it same as it is
private boolean startSingleSignOn(Activity activity, String applicationId,
String[] permissions, int activityCode) {
boolean didSucceed = true;
Intent intent = new Intent();
intent.setClassName("com.facebook.katana",
"com.facebook.katana.ProxyAuth");
intent.putExtra("client_id", applicationId);
if (permissions.length > 0) {
intent.putExtra("scope", TextUtils.join(",", permissions));
}
// Verify that the application whose package name is
// com.facebook.katana.ProxyAuth
// has the expected FB app signature.
if (!validateActivityIntent(activity, intent)) {
return false;
}
mAuthActivity = activity;
mAuthPermissions = permissions;
mAuthActivityCode = activityCode;
try {
activity.startActivityForResult(intent, activityCode);
} catch (ActivityNotFoundException e) {
didSucceed = false;
}
return didSucceed;
}
In my activity that calls the authorizing and handles what to do after authorizing here's my code
private void setFacebookConnection() {
// progressBar.setVisibility(View.VISIBLE);
facebook = new Facebook(Constants.FACEBOOK_APP_ID);
facebookAsyncRunner = new AsyncFacebookRunner(facebook);
// facebook.authorize(MerchantDetailsActivity.this, Constants.FACEBOOK_PERMISSIONS,
// Facebook.FORCE_DIALOG_AUTH, new LoginDialogListener());
facebook.authorize(MerchantDetailsActivity.this, Constants.FACEBOOK_PERMISSIONS, new LoginDialogListener());
}
private class LoginDialogListener implements Facebook.DialogListener {
public void onComplete(Bundle values) {
String token = facebook.getAccessToken();
long token_expires = facebook.getAccessExpires();
Log.d(TAG, "AccessToken: " + token);
Log.d(TAG, "AccessExpires: " + token_expires);
facebookSharedPreferences = PreferenceManager
.getDefaultSharedPreferences(context);
facebookSharedPreferences.edit()
.putLong(Constants.FACEBOOK_ACCESS_EXPIRES, token_expires)
.commit();
facebookSharedPreferences.edit()
.putString(Constants.FACEBOOK_ACCESS_TOKEN, token).commit();
facebookAsyncRunner.request("me", new IDRequestListener());
shareFBPost();
}
It seems that when the user is already authorized it doesn't go inside my LoginDialogListener
If you will use this guide you will be able to open Facebook app for login
After implementing Facebook auth, initialize Facebook SDK in your Application class or in activity which uses Facebook login
// initialize facebook sdk and app events logger
FacebookSdk.sdkInitialize(getApplicationContext());
Then you can use the class below to login
public class FacebookAuth {
private static FacebookAuth instance;
private OnLoginDataReadyListener mResponseListener;
public static synchronized FacebookAuth getInstance() {
if (instance == null) {
instance = new FacebookAuth();
}
return instance;
}
/**
* Call if you want the user to login with his facebook account
* #param activity needed to initialize the Facebook LoginManager
* #param listener used to set the login listener
*/
public void facebookLogin(Activity activity, OnLoginDataReadyListener listener, CallbackManager callbackManager) {
mResponseListener = listener;
LoginManager.getInstance().logInWithReadPermissions(activity, Arrays.asList("public_profile", "user_friends", "email"));
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
getUserData();
}
#Override
public void onCancel() {
if (mResponseListener != null) {
mResponseListener.onCanceled();
}
}
#Override
public void onError(FacebookException error) {
if (mResponseListener != null) {
mResponseListener.onCanceled();
}
}
});
}
/**
* Creates an Facebook Graph request witch will grab the user data
* such as name id and picture for now
*/
public void getUserData() {
GraphRequest request = GraphRequest.newMeRequest( AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
if (mResponseListener != null) {
mResponseListener.onLoginDataReady(object);
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "picture.height(200).width(200),cover,location,birthday,first_name,last_name,email,gender,name");
request.setParameters(parameters);
request.executeAsync();
}
public interface OnLoginDataReadyListener {
void onLoginDataReady(JSONObject facebookData);
void onCanceled();
}
}
Once you've implemented the above solution, în your activity create a CallbackManager
CallbackManager mCallbackManager = CallbackManager.Factory.create();
Then in button click listener you can login your user as following
FacebookAuth.getInstance().facebookLogin(activity, dataReadyListener, mCallbackManager);
And finally in onActivityResult()
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mCallbackManager.onActivityResult(requestCode, resultCode, data);
}
Hope this will help you ))
I use the latest Facebook SDK instead and follow these steps. It is important to add onActivityResult for Facebook login callbackManager.

Cannot get the facebook's user's timeline with api 2.5

I'm trying to get the facebook's user's timeline in my Android app.
Here my code :
mLoginButton.setReadPermissions(Arrays.asList("user_about_me", "user_friends", "user_likes",
"user_photos", "user_relationships", "user_posts",
"user_status"));
// If using in a fragment
mLoginButton.setFragment(this);
// Other app specific specialization
// Callback registration
mLoginButton.registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
mAccessToken = loginResult.getAccessToken();
for (String permission : loginResult.getRecentlyGrantedPermissions()) {
Log.d(LOG_TAG, "Granted Permission:" + permission);
}
getUserFeed();
}
#Override
public void onCancel() {
// App code
}
#Override
public void onError(FacebookException exception) {
// App code
}
});
And after the login, I launch this :
private void getUserFeed() {
Bundle params = new Bundle();
params.putInt("limit", 25);
params.putString("fields", "id,name,link,full_picture,message,story,picture,type,place,from,to");
params.putBoolean("summary", true);
/* make the API call */
new GraphRequest(
AccessToken.getCurrentAccessToken(),
"/me/home",
params,
HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
try {
final JSONArray data = response.getJSONObject().getJSONArray("data");
//currentJson = response.getJSONObject();
} catch (JSONException e) {
Log.e("Error: ", e.toString());
}
}
}
).executeAsync();
}
I have this respond code from Facebook :
Requires extended permission: read_stream
I know this permission is depreceted, I'm using the latest API 2.5.
Do you know if we can continue to get the user's timeline now, if I replace the "/me/home" by "/me/feed" it's ok, but I just get my posts, not my entire timeline.
Thanks :)
Do you know if we can continue to get the user's timeline now,
No, you can’t.
if I replace the "/me/home" by "/me/feed" it's ok, but I just get my posts, not my entire timeline.
/me/home was deprecated together with the permission.
/me/feed is what you can get now, and that’s it.
Which posts you can expect to see is listed here: https://developers.facebook.com/docs/graph-api/reference/v2.5/user/feed#readperms

Add read and publish permission together to ParseFacebookUtils

Above is my code but i cant find out together usage, always gives error
Cannot pass a publish or manage permission (publish_actions) to a request for read authorization
This is my Permission list
private Collection<String> permissions = new ArrayList<>();
permissions.add("public_profile");
permissions.add("email");
permissions.add("user_birthday");
permissions.add("publish_actions");
And this is login request
ParseFacebookUtils.logInWithReadPermissionsInBackground(activity, permissions, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException parseException) {
if (parseUser == null) {
} else {
}
}
});
How can i use this together?
After long hours, this is solution. You must behave twice login to facebook. Once is publish and other one is read permissions. If you need public profile data , just publish permission is enough but in my case i need birthday, email, etc.. So code is below;
These are my permissions lists;
Collection<String> readPermissions = new ArrayList<>();
readPermissions.add("public_profile");
readPermissions.add("email");
readPermissions.add("user_birthday");
Collection<String> publishPermissions = new ArrayList<>();
publishPermissions.add("publish_actions");
Firstly, I should login with readpermission
ParseFacebookUtils.logInWithReadPermissionsInBackground(activity, readPermissions, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException parseException) {
if (parseUser == null) {
listener.onFailure(new UserCancelledFacebookLogin());
} else {
getPublishPermissions(parseUser);
}
}
});
After this, here my "getPublishPermissions" method; FacebookRequestListener is my own listener , don't care/mind delete it.
public void getPublishPermissions(final ParseUser parseUser) {
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
// User succesfully login with all permissions
// After this with these json and ParseUser , you can save your user to Parse
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,first_name,last_name,name,email,gender,birthday");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException facebookException) {
}
});
LoginManager.getInstance().logInWithPublishPermissions(activity, publishPermissions);
}
that's all folks =)
happy coding to everyone
The error message means you should not request read and write permissions at the same time. Login with read permissions when the User enters your App, request write permission (publish_actions) only right before you post.
Use ParseFacebookUtils.logInWithPublishPermissionsInBackground for that.
That error message is already well known, take a look at some other thread about it:
How to set permission "publish_actions" in LoginButton using facebook sdk?
Facebook, setReadPermissions and setPublishPermissions
facebook login Cannot pass a publish or manage permission (email) to a request for read authorization
You need to do a POST request instead of a GET one. See:
https://developers.facebook.com/docs/graph-api/reference/v2.2/user/scores/#publish
Sample:
Bundle param = new Bundle();
param.putString("message", "picture caption");
param.putByteArray("picture", ImageBytes);
mAsyncRunner.request("me/photos", param, "POST", new SampleUploadListener());
this is your answer check link

Post Id facebook share dialog always return null in Android

I used test app id and log on by test user create at dash_board app on facebook develop site, require pulish_actions permission when login using login button widget of facebook sdk but result get postid always = null.
Here is my code:
....
shareDialog = new ShareDialog(MainActivity.this);
shareDialog.registerCallback(callbackManager, new FacebookCallback<Sharer.Result>() {
#Override
public void onSuccess(Sharer.Result result) {
if (result.getPostId() != null)
Log.e(TAG, result.getPostId());
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException e) {
}
});
pulishButton.setOnClickListener(this);
try{
loginButton.setPublishPermissions(new String[]{"publish_actions","publish_stream"});
}catch (FacebookException e){
e.printStackTrace();
}
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.e(TAG, "success");
loginButton.setEnabled(false);
pulishButton.setEnabled(true);
GraphRequest.newMeRequest(
loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject json, GraphResponse response) {
if (response.getError() != null) {
// handle error
System.out.println("ERROR");
} else {
System.out.println("Success");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}).executeAsync();
}
#Override
public void onCancel() {
Log.e(TAG, "On cancel");
}
#Override
public void onError(FacebookException e) {
Log.d(TAG, e.toString());
}
});
The solution is to force ShareDialog to use Feed mode and avoid using FB's App for sharing:
shareDialog.show(linkContent, ShareDialog.Mode.FEED);
I believe this is a bug by FB. They don't send postId to onSuccess callback when using FB App for sharing (postId = null), but they do if you use Feed.
I've heard you can avoid the "postId=null" problem by using Facebook Login and demanding "publish_actions" permission. But I don't think this is the correct way to deal with this problem. Regarding the mentioned permission Facebook states:
Publishing via dialogs or social plugins does not require this permission. Do not request review of this permission if you're only using Share dialog, Feed Dialog, Message Dialog etc, or Social Plugins (e.g. the Like Button.)
Facebook's docs on Share Dialog:
This does not require Facebook Login or any extended permissions, so it is the easiest way to enable sharing on the web.
Facebook confirmed this issue in their latest update:
https://developers.facebook.com/support/bugs/478167629274681/
https://developers.facebook.com/support/bugs/647119912303459/
You can't login directly with "publish_action", you have to first login with any read permission then ask for for publish permissions
https://developers.facebook.com/docs/facebook-login/permissions/v2.4#publishing

Categories

Resources