Facebook API doesn't return email - java

I know that this question has been asked, but there is only one answer pretty much or is not even answered.
I dont know if it's my lack of understanding or lack of Facebook documentation, but so far i have this code to retrieve user email.
callbackManager = CallbackManager.Factory.create();
mFbLoginManager.registerCallback(
callbackManager,
new FacebookCallback < LoginResult > () {
#Override
public void onSuccess(final LoginResult loginResult) {
// Handle success
Log.i(TAG, "callBack Login Result: LoginManager success - " + loginResult.toString());
GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject userObject, GraphResponse response) {
if (response.getError() == null) {
try {
AccessToken token = AccessToken.getCurrentAccessToken();
Log.e(TAG, token.getToken());
Log.e(TAG, userObject.toString());
email = userObject.getString("email");
} catch (JSONException ex) {
Log.e(TAG, "Not such permissions for email!");
ex.printStackTrace();
}
Log.d(TAG, "Email fetched: " + email);
}else{
Log.e(TAG, "Something went wrong with fetching email with GraphRequest");
}
}
}).executeAsync();
}
The JSON string returns only the name and the id, therefore my email variable is empty.
The part i am troubled with is that when i test it on Graph Explorer or with that link, i get the email.
I have se permissions also on the developers site dashboard and also in my code(that's inside onClick() when user press the facebook login button):
mFbLoginManager.logInWithReadPermissions(LoginActivity.this, Arrays.asList("user_photos", "email", "public_profile")
So i am not sure what is the problem in my code. The login button is custom and not the facebook LoginButton, i dont know if that matters.
Every help is welcome

Add below depandancy in Gradle
implementation 'com.facebook.android:facebook-android-sdk:4.11.0'
enter code here
FacebookSdk.sdkInitialize(this);
callbackManager =CallbackManager.Factory.create();
// -----start putting in oncreate-----------------------
LoginManager.getInstance().logInWithReadPermissions(UserActivity.this, Arrays.asList("public_profile", "user_friends","email"));
facebookTime();
//----onclicklisterner ---------------/
callbackManager.onActivityResult(requestCode,resultCode,data);
//---onactivityresult-------------/
public void facebookTime() {
LoginManager.getInstance().registerCallback(callbackManager,
new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
System.out.println("Success");
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
// Util.showCenteredToast(getActivity(), "object" + object);
// Util.showCenteredToast(getActivity(), "GraphResponse" + response);
try {
strEmail = object.getString("email");
strUserName = object.getString("name");
String id = object.getString("id");
// write your code here
//asyncTask.iSocialMediaResponse = LoginFragment.this;
asyncTask.execute();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "email,name");
//parameters.putString("fields", "user_friends");
request.setParameters(parameters);
//Log.e(" About to Graph Call", " ");
request.executeAsync();
}
#Override
public void onCancel() {
// App code
Util.showCenteredToast(UserActivity.this, "oncancel");
}
#Override
public void onError(FacebookException exception) {
// App code
Util.showCenteredToast(UserActivity.this, "exception" + exception);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}

Related

How to use instagram_graph_user_profile permission in Java

I searched a lot about how to use the instagram_graph_user_profile permission in Java but I can't find anything about it.
This is my code:
private void init_instagram() {
FacebookSdk.setApplicationId(getString(R.string.facebook_app_id));
FacebookSdk.sdkInitialize(this.getApplicationContext());
if (BuildConfig.DEBUG) {
FacebookSdk.setIsDebugEnabled(true);
FacebookSdk.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
}
callbackManager = CallbackManager.Factory.create();
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), (object, response) -> {
if (object != null) {
Log.e(TAG, object.toString());
} else {
Log.e(TAG, "null");
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "instagram_graph_user_profile");//instagram_graph_user_profile
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
Log.e(TAG, "onCancel");
}
#Override
public void onError(FacebookException exception) {
Log.e(TAG, exception.toString());
}
});
}
When I press the button:
connectInstagram.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LoginManager.getInstance().logInWithReadPermissions(MyProfileActivity.this,
Arrays.asList("instagram_graph_user_profile"));
}
});
It returns this error message:
Unsupported get request. Object with ID '2674********80' does not exist, cannot be loaded due to missing permissions, or does not support this operation
and redirect to a facebook page with message "Sorry, something went wrong. We are working on It and we'll get it fixed as soon as can."
or give me this error in console log:
E/GraphResponse: {HttpStatus: 400, errorCode: 104, subErrorCode: -1, errorType: OAuthException, errorMessage: An access token is required to request this resource.}
I searched a lot about how to use the instagram_graph_user_profile permission in Java but I can't find anything about it.
This is my code:
private void init_instagram() {
FacebookSdk.setApplicationId(getString(R.string.facebook_app_id));
FacebookSdk.sdkInitialize(this.getApplicationContext());
if (BuildConfig.DEBUG) {
FacebookSdk.setIsDebugEnabled(true);
FacebookSdk.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
}
callbackManager = CallbackManager.Factory.create();
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), (object, response) -> {
if (object != null) {
Log.e(TAG, object.toString());
} else {
Log.e(TAG, "null");
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "instagram_graph_user_profile");//instagram_graph_user_profile
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
Log.e(TAG, "onCancel");
}
#Override
public void onError(FacebookException exception) {
Log.e(TAG, exception.toString());
}
});
}
When I press the button:
connectInstagram.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LoginManager.getInstance().logInWithReadPermissions(MyProfileActivity.this,
Arrays.asList("instagram_graph_user_profile"));
}
});
It returns this error message:
Unsupported get request. Object with ID '2674********80' does not exist, cannot be loaded due to missing permissions, or does not support this operation
and redirect to a facebook page with message "Sorry, something went wrong. We are working on It and we'll get it fixed as soon as can."
or give me this error in console log:
E/GraphResponse: {HttpStatus: 400, errorCode: 104, subErrorCode: -1, errorType: OAuthException, errorMessage: An access token is required to request this resource.}

How to get user Gender and birthday from facebook in android

I am Trying to get gender and birthday of current login user from Facebook, but I always getting (id, email, name) I have search everything related to this but I didn't get exactly that for I am looking. below code, I have Trying that's not working.
facebookLoginButton = (LoginButton)view .findViewById(R.id.fragment_login_facebook);
facebookLoginButton.setFragment(this);
callbackManager = CallbackManager.Factory.create();
facebookLoginButton.setReadPermissions(Arrays.asList("public_profile", "email", "user_birthday", "user_friends"));
callbackManager = CallbackManager.Factory.create();
facebookLoginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
private ProfileTracker mProfileTracker;
#Override
public void onSuccess(LoginResult loginResult) {
String accessTocken = loginResult.getAccessToken().getToken().toString();
Log.v("TAG", "Access Token " + loginResult.getAccessToken().getToken());
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
String email = object.getString("birthday");
String name = object.getString("gender");
Toast.makeText(getActivity().getApplicationContext(),email + " " + name ,Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender,birthday");
request.setParameters(parameters);
request.executeAsync();
if (com.facebook.Profile.getCurrentProfile() == null){
mProfileTracker = new ProfileTracker() {
#Override
protected void onCurrentProfileChanged(com.facebook.Profile oldProfile, com.facebook.Profile currentProfile) {
mProfileTracker.stopTracking();
}
};
mProfileTracker.startTracking();
} else {
com.facebook.Profile profile = com.facebook.Profile.getCurrentProfile();
}
try {
URL image_value = new URL("http://graph.facebook.com/" + loginResult.getAccessToken().getUserId() + "/picture?type=large");
Log.v(Constants.TAG, image_value + "");
} catch (Exception e) {
}
}
#Override
public void onCancel() {
Log.e("TAG", "wrong");
}
#Override
public void onError(FacebookException error) {
Log.e("TAG", "wrong");
}
});
Where facebookLoginButton is LoginButton and callbackManager is CallbackManager
Please help me thanks in advance.
Facebook gender & birthday needs app review.
Apps that Require App Review
Your app requires review if it uses the following functionality:
Facebook Login and also asks for a person's birthday, location, hometown, gender, age range, or link to profile
Check the link for more details.

Check whether a user used facebook sdk to login into app previously

Currently I have a code where I have a facebook login button in my login page. And right now I'm trying to make a check first whether a user already logged in into my app using facebook when the facebook login button is clicked. I read the facebook documentation here on how to do it but I have no idea where to apply this in my code.
loginbutton
LoginButton loginButton = (LoginButton) findViewById(R.id.button_facebook_login);
loginButton.setReadPermissions(Arrays.asList("email","public_profile"));
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.d("LoginResult : ", loginResult.getAccessToken().getToken());
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.v("LoginActivity", response.toString());
try{
// Application code
String email = object.getString("email");
String firstName = object.getString("first_name");
String lastName = object.getString("last_name");
ArrayList<String> publicProfile = new ArrayList<String>();
publicProfile.add(email);
publicProfile.add(firstName);
publicProfile.add(lastName);
new RegisterGetList(LoginActivity.this,mProgressView,LoginActivity.this, publicProfile).execute();
}
catch (JSONException e1){
e1.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,first_name,last_name,email");
request.setParameters(parameters);
request.executeAsync();
}
We will get Facebook user account id,So from the backend you have to check whether that userId is already registered or not.Then you can solve the issue.
You can store the email in shared preferences and you can check if shared preferences is null or not.
SharedPreferences sp=PreferenceManager.getDefaultSharedPreferences(context);
String email=sp.getString("email",null);
if(email==null)
{
//first log in
//store the email in shared prefernces
SharedPreferences.Editor editor = sharedPreferences.edit()
editor.putString("email",value);
editor.apply();
}
else
{
//already logged in
}
clear the sp when user wil logout.
Check this in your onCreate that user is logged in or not.
if (AccessToken.getCurrentAccessToken() != null) {
getUserDetails();
} else{
loginButton.setReadPermissions(Arrays.asList("public_profile", "email"));
}
and getting user details using :
private void getUserDetails() {
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(
JSONObject object,
GraphResponse response) {
try {
Log.i(TAG, "Response >>: " + object.toString());
String userID = object.getString("id");
String strName = object.getString("name").toString();
String strgander = object.getString("gender").toString();
String strEmail = object.getString("email").toString();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,link,gender,age_range,cover,picture,location");
request.setParameters(parameters);
request.executeAsync();
}
set permission in Login button's onClick.
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loginButton.setReadPermissions(Arrays.asList("public_profile", "email"));
}
});
set callback to Login button using
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
And, finally just call "getUserDetails()" inside onSuccess callback of your login button.

Android Facebook SDK 4.X , how to get Email address and Facebook Access Token to pass it to Web Service

EDIT :
My Question is how to get Email , UserId , Facebook Authentication with Facebook SDK 4.X , at this moment , with Ming Respond , i know how can i get Email , User Id , so my question is how to get Facebook Authentication since Session and GraphUser has just been replaced by LoginManager and AccessToken and there is no information about it?
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.facebook.AccessToken;
import com.facebook.AccessTokenTracker;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.Profile;
import com.facebook.ProfileTracker;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import java.util.Arrays;
public class RegisterActivity extends Activity {
private String fbUserID;
private String fbProfileName;
private String fbAuthToken;
private LoginButton fbLoginBtn;
private static final String TAG = "FacebookLogin";
CallbackManager callbackManager;
private AccessTokenTracker accessTokenTracker;
private ProfileTracker profileTracker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register_activity);
fbLoginBtn = (LoginButton) findViewById(R.id.connect_with_facebook_button);
fbLoginBtn.setReadPermissions(Arrays.asList("email", "user_photos", "public_profile"));
fbLoginBtn.setBackgroundResource(R.drawable.connect_facebook_button);
accessTokenTracker = new AccessTokenTracker() {
#Override
protected void onCurrentAccessTokenChanged(
AccessToken oldAccessToken,
AccessToken currentAccessToken) {
fbAuthToken = currentAccessToken.getToken();
fbUserID = currentAccessToken.getUserId();
Log.d(TAG, "User id: " + fbUserID);
Log.d(TAG, "Access token is: " + fbAuthToken);
}
};
profileTracker = new ProfileTracker() {
#Override
protected void onCurrentProfileChanged(
Profile oldProfile,
Profile currentProfile) {
fbProfileName = currentProfile.getName();
Log.d(TAG, "User name: " + fbProfileName );
}
};
fbLoginBtn.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
}
#Override
public void onCancel() {
// App code
}
#Override
public void onError(FacebookException exception) {
// App code
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
GraphRequest request = GraphRequest.newMeRequest(
accessToken,
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(
JSONObject user,
GraphResponse response) {
String id = user.optString("id");
String firstName = user.optString("first_name");
String lastName = user.optString("last_name");
String email = user.optString("email");
}
#Override
public void onSaveInstanceState(Bundle savedState) {
super.onSaveInstanceState(savedState);
}
fbLoginBtn.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
GraphRequest.newMeRequest(
loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject me, GraphResponse response) {
if (response.getError() != null) {
// handle error
} else {
String email = me.optString("email");
String id = me.optString("id");
// send email and id to your web server
}
}
}).executeAsync();
}
#Override
public void onCancel() {
// App code
}
#Override
public void onError(FacebookException exception) {
// App code
}
});
Easiest answer that i found after hours of searching is as follows,the highest voted answer didn't work for me and email was alway empty
LoginManager.getInstance().registerCallback(mCallbackManager,
new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object,GraphResponse response) {
JSONObject json = response.getJSONObject();
try {
if(json != null){
String text = json.getString("email");
Log.d("email",text);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,link,email,picture");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
// App code
}
#Override
public void onError(FacebookException exception) {
// App code
}
});
I believe setting parameters as required fields to the Graph Request is a crucial thing here. You can also use this code with LoginButton, works without issue.
****** Update********
After using this code with many accounts found that if the email isn't verified it won't be returned, in such case following code helped along with abo
facebookLoginButton.setReadPermissions("email");
Hope this helps further
I must add extra field for user Email.
//register facebook login callback
LoginManager.getInstance().registerCallback(mCallbackManager, new FacebookCallback<LoginResult>()
{
#Override
public void onSuccess (LoginResult loginResult)
{
Log.d(TAG, "FB: login success");
showLoading(true);
final String token = loginResult.getAccessToken().getToken();
//prepare fields with email
String[] requiredFields = new String[]{"email"};
Bundle parameters = new Bundle();
parameters.putString("fields", TextUtils.join(",", requiredFields));
GraphRequest requestEmail = new GraphRequest(loginResult.getAccessToken(), "me", parameters, null, new GraphRequest.Callback()
{
#Override
public void onCompleted (GraphResponse response)
{
if (response != null)
{
GraphRequest.GraphJSONObjectCallback callbackEmail = new GraphRequest.GraphJSONObjectCallback()
{
#Override
public void onCompleted (JSONObject me, GraphResponse response)
{
if (response.getError() != null)
{
Log.d(TAG, "FB: cannot parse email");
showDialog(getString(R.string.dialog_message_unknown_error));
showLoading(false);
}
else
{
String email = me.optString("email");
// send email and id to your web server
//...
}
}
};
callbackEmail.onCompleted(response.getJSONObject(), response);
}
}
});
requestEmail.executeAsync();
}
#Override
public void onCancel ()
{
Log.d(TAG, "FB: login cancel");
showDialog(getString(R.string.dialog_message_unknown_error));
}
#Override
public void onError (FacebookException e)
{
Log.d(TAG, "FB: login error " + e.getMessage());
showDialog(getString(R.string.dialog_message_unknown_error));
}
});

Facebook - Post to wall

I have this code.. The only working here is the Login... I want to achieve the Publish to wall or feed dialog.. I have here the code for the wall post but It still not working.. Any help will be appreciated... I followed this link for my Login
[a link] http://www.kpbird.com/2013/03/android-login-using-facebook-sdk-30.html
I am trying to embed the post status in this Login..
public class FacebookActivity extends FragmentActivity {
private Button publishButton;
private String TAG = "FacebookActivity";
private TextView lblEmail;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.facebook_activity);
lblEmail = (TextView) findViewById(R.id.lblEmail);
LoginButton authButton = (LoginButton) findViewById(R.id.authButton);
authButton.setOnErrorListener(new OnErrorListener(){
#Override
public void onError(FacebookException error) {
Log.i(TAG, "Error " + error.getMessage());
}
// TODO Auto-generated method stub
});
// set permission list, Don't forget to add email
authButton.setReadPermissions(Arrays.asList("basic_info","email"));
// session state call back event
authButton.setSessionStatusCallback(new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Log.i(TAG,"Access Token"+ session.getAccessToken());
Request.executeMeRequestAsync(session,
new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user,Response response) {
if (user != null) {
Log.i(TAG,"User ID "+ user.getId());
Log.i(TAG,"Email "+ user.asMap().get("email"));
lblEmail.setText(user.asMap().get("email").toString());
}
}
});
publishButton.setVisibility(View.VISIBLE);
}
else if (state.isClosed()) {
publishButton.setVisibility(View.INVISIBLE);
}
}
});
publishButton = (Button) findViewById(R.id.publishButton);
publishButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
publishFeedDialog();
}
});
}
private void publishFeedDialog() {
Bundle params = new Bundle();
params.putString("name", "Facebook SDK for Android");
params.putString("caption", "Build great social apps and get more installs.");
params.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
params.putString("link", "https://developers.facebook.com/android");
params.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
WebDialog feedDialog = (
new WebDialog.FeedDialogBuilder(getActivity(),
Session.getActiveSession(),
params))
.setOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(Bundle values,
FacebookException error) {
if (error == null) {
// When the story is posted, echo the success
// and the post Id.
final String postId = values.getString("post_id");
if (postId != null) {
Toast.makeText(getActivity(),
"Posted story, id: "+postId,
Toast.LENGTH_SHORT).show();
} else {
// User clicked the Cancel button
Toast.makeText(getActivity().getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
}
} else if (error instanceof FacebookOperationCanceledException) {
// User clicked the "x" button
Toast.makeText(getActivity().getApplicationContext(),
"Publish cancelled",
Toast.LENGTH_SHORT).show();
} else {
// Generic, ex: network error
Toast.makeText(getActivity().getApplicationContext(),
"Error posting story",
Toast.LENGTH_SHORT).show();
}
}
})
.build();
feedDialog.show();
}
protected ContextWrapper getActivity() {
// TODO Auto-generated method stub
return null;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
}

Categories