I implemented Facebook in app and fetched name,email and id from graph api,Now i cannot get email it from graph api and i passed id,name,email fields but got only id,name but not email.Is it change any privacy policy from facebook.
I'm Using https://graph.facebook.com/me?access_token=(token here)&fields=id,name,email
Try With This Running successfully
private void facebookLogin() {
mFaceBookloginButton = (LoginButton) findViewById(R.id.login_button);
mFaceBookloginButton.setReadPermissions("public_profile");
mFaceBookloginButton.setReadPermissions("email");
callbackManager = CallbackManager.Factory.create();
mFaceBookloginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
MyLog.debug("Name" + loginResult.getAccessToken(), ActivityLogin.class);
Profile profile = Profile.getCurrentProfile();
if (profile != null) {
MyLog.debug("Pic Url" + profile.getProfilePictureUri(200, 200), ActivityLogin.class);
MyLog.debug("User Name" + profile.getFirstName(), ActivityLogin.class);
MyLog.debug("User Email" + profile.getLastName(), ActivityLogin.class);
}
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
FacebookUser facebookUser = null;
try {
if (object != null) {
facebookUser = new FacebookUser();
if (object.has("id")) {
facebookUser.setId(object.getString("id"));
}
if (object.has("first_name")) {
facebookUser.setFirst_name(object.getString("first_name"));
}
if (object.has("last_name"))
facebookUser.setLast_name(object.getString("last_name"));
if (object.has("email"))
facebookUser.setEmail(object.getString("email"));
}
if (facebookUser != null) {
hitSocialLogin(facebookUser);
LoginManager.getInstance().logOut();
}
} catch (Exception e) {
MyLog.printException(e);
} finally {
LoginManager.getInstance().logOut();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id, first_name, last_name, email,gender, birthday, location"); // Parámetros que pedimos a facebook
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
MyLog.debug("on Cancel", ActivityLogin.class);
}
#Override
public void onError(FacebookException exception) {
MyLog.debug("on Cancel" + exception, ActivityLogin.class);
}
});
}
Related
I'm trying to get name and email from facebook login.
I'm using: compile 'com.facebook.android:facebook-android-sdk:4.+'
I can get into onSuccess but the code does not get into GraphRequest and I think that's why I can't get name and email (I'd also like get Profile picture)
I got the autogenerated code (GraphRequest) from facebook developer Explorer Api Graph
public class LoginActivity
{
LoginButton buttonLoginFacebook;
#Nullable
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
buttonLoginFacebook = (LoginButton) findViewById(R.id.connectWithFbButton);
buttonLoginFacebook.setReadPermissions(Arrays.asList(
"public_profile", "email"));
FacebookSdk.setIsDebugEnabled(true);
FacebookSdk.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
FacebookSdk.addLoggingBehavior(LoggingBehavior.REQUESTS);
buttonLoginFacebook.setOnClickListener(this);
buttonLoginFacebook.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
//----->THE CODE JUMPS FROM HERE
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
mensajeFACEBOOK="TRYING TO GET NAME";
}
});
//----->TO HERE
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,first_name,last_name");
request.setParameters(parameters);
request.executeAsync();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException error) {
}
});
}
}
This is how i do it. Hope this helps.
private void registerCallBackMethod(){
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(final LoginResult loginResult) {
final String accessToken = loginResult.getAccessToken().getUserId();
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject jsonObject,
GraphResponse response) {
// Getting FB User Data and checking for null
Bundle facebookData = getFacebookData(jsonObject);
String email = "";
String first_name = "";
String last_name = "";
String profile_pic = "";
if (facebookData.getString("email") != null && !TextUtils.isEmpty(facebookData.getString("email")))
email = facebookData.getString("email");
else
email = "";
if (facebookData.getString("first_name") != null && !TextUtils.isEmpty(facebookData.getString("first_name")))
first_name = facebookData.getString("first_name");
else
first_name = "";
if (facebookData.getString("last_name") != null && !TextUtils.isEmpty(facebookData.getString("last_name")))
last_name = facebookData.getString("last_name");
else
last_name = "";
if (facebookData.getString("profile_pic") != null && !TextUtils.isEmpty(facebookData.getString("profile_pic")))
profile_pic = facebookData.getString("profile_pic");
else
profile_pic = "";
sendValues(first_name+" "+last_name,email, "", "", accessToken, "Facebook",profile_pic);
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,first_name,last_name,email,gender");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel () {
Log.d("TAG", "Login attempt cancelled.");
}
#Override
public void onError (FacebookException e){
e.printStackTrace();
Log.d("TAG", "Login attempt failed.");
deleteAccessToken();
}
}
);
}
private Bundle getFacebookData(JSONObject object) {
Bundle bundle = new Bundle();
try {
String id = object.getString("id");
URL profile_pic;
try {
profile_pic = new URL("https://graph.facebook.com/" + id + "/picture?type=large");
Log.i("profile_pic", profile_pic + "");
bundle.putString("profile_pic", profile_pic.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
bundle.putString("idFacebook", id);
if (object.has("first_name"))
bundle.putString("first_name", object.getString("first_name"));
if (object.has("last_name"))
bundle.putString("last_name", object.getString("last_name"));
if (object.has("email"))
bundle.putString("email", object.getString("email"));
if (object.has("gender"))
bundle.putString("gender", object.getString("gender"));
} catch (Exception e) {
Log.d("TAG", "BUNDLE Exception : "+e.toString());
}
return bundle;
}
private void deleteAccessToken() {
AccessTokenTracker accessTokenTracker = new AccessTokenTracker() {
#Override
protected void onCurrentAccessTokenChanged(
AccessToken oldAccessToken,
AccessToken currentAccessToken) {
if (currentAccessToken == null){
//User logged out
LoginManager.getInstance().logOut();
}
}
};
}
Actually GraphRequest.executeAsync() is an async method with a callback onCompleted so to read the data you need to do it inside the callback.
buttonLoginFacebook.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) {
//Read the data you need from the GraphResponse here like this:
try {
String firstName = response.getJSONObject().getString("first_name");
String lastName = response.getJSONObject().getString("last_name");
String email = response.getJSONObject().getString("email");
String id = response.getJSONObject().getString("id");
String picture = response.getJSONObject().getJSONObject("picture").getJSONObject("data").getString("url");
} catch (JSONException e) {
e.printStackTrace();
}
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,first_name,last_name,picture.width(150).height(150)");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException error) {
}
});
Also included the profile picture field picture.width(150).height(150) as you asked
Any idea, why I cannot get email from Facebook? I got error like - No value for "email" or sth like that.
private void fbInit() {
// Initialize the SDK before executing any other operations,
FacebookSdk.sdkInitialize(getApplicationContext());
AppEventsLogger.activateApp(this);
callbackManager = CallbackManager.Factory.create();
// get new instance of fb
LoginManager.getInstance().registerCallback(callbackManager,
new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
loginResult.getAccessToken().getUserId();
getFbData(loginResult.getAccessToken().getUserId());
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException error) {
}
});
// access token tracker init
accessTokenTracker = new AccessTokenTracker() {
#Override
protected void onCurrentAccessTokenChanged(
AccessToken oldAccessToken,
AccessToken currentAccessToken) {
// Set the access token using
// currentAccessToken when it's loaded or set.
accessToken = currentAccessToken;
updateWithToken(currentAccessToken);
}
};
// If the access token is available already assign it.
accessToken = AccessToken.getCurrentAccessToken();
updateWithToken(accessToken);
// is this need?!
// profileTracker = new ProfileTracker() {
// #Override
// protected void onCurrentProfileChanged(
// Profile oldProfile,
// Profile currentProfile) {
// // App code
// }
// };
}
private void updateWithToken(AccessToken currentAccessToken) {
// this way I check if there is email permission which is needed to register/login
if (currentAccessToken != null
&& !currentAccessToken.getDeclinedPermissions().contains("email")
&& !currentAccessToken.getDeclinedPermissions().contains("basic_info")) {
// go to other activity (?)
} else {
ActivityUtils.showToast(this, "no email permission");
}
}
private void getFbPermissions() {
Collection<String> permissions = Arrays.asList("public_profile", "email", "user_photos", "user_birthday");
LoginManager.getInstance().logInWithReadPermissions(this, permissions);
}
private void getFbData(String userId) {
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
if (response != null) {
try {
Log.i("LoginActivityFbResponse", response.toString());
ActivityUtils.showToast(getActivity(),
object.getString("id") + object.getString("name") + object.getString("email")
+ object.getJSONArray("location").getString(1) + object.getString("locale")
+ object.getString("birthday") + object.getString("gender"));
// TODO: try to login
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id, name, email");
request.setParameters(parameters);
request.executeAsync();
}
BTW. I want to get from Facebook at least this data: email, id, gender, birthday, location_name.
You get Error with birthday because you dont have permission of birthday in your GraphRequest.
Use it like :
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender,birthday,picture.type(large)");
request.setParameters(parameters);
request.executeAsync();
Can you try this and come with result ?
I added Facebook SDK to my android app. I used callBackManager to handle the login button. Now I'm logged to Facebook and I want to save my fb profile information (profile photo, cellphone, name, birthdate..) before calling the function goRegisterActivity(). Any help?
// Handle Facebook Login Button
callbackManager = CallbackManager.Factory.create();
facebookLoginBtn = (LoginButton) findViewById(R.id.login_facebook_btn);
facebookLoginBtn.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
//Go to register first step activity
goRegisterActivity();
}
#Override
public void onCancel() {
//Do nothing
}
#Override
public void onError(FacebookException error) {
Toast.makeText(getApplicationContext(),"Oups! can't login Facebook. Please try again later.", Toast.LENGTH_SHORT)
.show();
}});
}
Call the graph API in the onSuccess() method:
facebookLogin.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) {
Log.i("LoginActivity", response.toString());
// Get facebook data from login
Bundle bFacebookData = getFacebookData(object);
emailStr = bFacebookData.get("email").toString();
fnameStr = bFacebookData.get("first_name").toString();
lnameStr = bFacebookData.get("last_name").toString();
facebookIdStr = bFacebookData.get("idFacebook").toString();
genderStr = bFacebookData.get("gender").toString();
dp_url = bFacebookData.get("profile_pic").toString();
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id, first_name, last_name, email,gender, birthday, location"); // Parámetros que pedimos a facebook
request.setParameters(parameters);
request.executeAsync();
}
And The getFacebookData(object) method should be like:
private Bundle getFacebookData(JSONObject object) {
try {
bundle = new Bundle();
String id = object.getString("id");
try {
URL profile_pic = new URL("https://graph.facebook.com/" + id + "/picture?width=200&height=150");
Log.i("profile_pic", profile_pic + "");
bundle.putString("profile_pic", profile_pic.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
bundle.putString("idFacebook", id);
if (object.has("first_name"))
bundle.putString("first_name", object.getString("first_name"));
if (object.has("last_name"))
bundle.putString("last_name", object.getString("last_name"));
if (object.has("email"))
bundle.putString("email", object.getString("email"));
if (object.has("gender"))
bundle.putString("gender", object.getString("gender"));
if (object.has("birthday"))
bundle.putString("birthday", object.getString("birthday"));
if (object.has("location"))
bundle.putString("location", object.getJSONObject("location").getString("name"));
System.out.println("BUNDLEEE: "+bundle);
return bundle;
} catch (JSONException e) {
e.printStackTrace();
}
return bundle;
}
This works for me. You can use ProfileTracker also, but I find this more reliable.
Thanks
I have done upto the code below and can succesfully authenticate and login Facebook user.
I have compile 'com.backendless:backendless:3.0.15.1' in my build gradle.
private FacebookCallback<LoginResult> mCallBack = new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
// mDialog.dismiss();
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.e("response: ", response + "");
user = new User();
user.facebookID = object.optString("id");
user.name = object.optString("name");
user.email = object.optString("email");
user.gender = object.optString("gender");
user.locale = object.optString("locale");
Utils.setCurrentUser(user, LoginActivity.this);
startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish();
Toast.makeText(LoginActivity.this, "Logged in as " + user.name, Toast.LENGTH_LONG).show();
}
}
);
Bundle parameters = new Bundle();
parameters.putString("fields", "id, name, email, gender, locale, birthday, picture.width(80).height(80)");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
Log.i(TAG, "LoginButton FacebookCallback onCancel");
}
#Override
public void onError(FacebookException error) {
Log.i(TAG, "LoginButton FacebookCallback onError:: "+error.getMessage());
Log.i(TAG, "Exception:: "+error.getStackTrace());
}
};
I'm currently creating a test application to test using the latest facebook SDK to update our existing application problem is that I need to get the email address which I know depends if the user has provided one on his account. Now the account I'm using to test provides one for sure but for unknown reason the facebook SDK only provides the user_id and the fullname of the account and nothing else. I'm confused on this since the the SDK3 and above provides more information than the updated SDK4 and I'm lost on how to get the email as all the answers I've seen so far doesn't provide the email on my end. Here's my code so far:
Login Button
#OnClick(R.id.btn_login)
public void loginFacebook(){
LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile", "email"));
}
LoginManager Callback:
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
requestUserProfile(loginResult);
}
#Override
public void onCancel() {
Toast.makeText(getBaseContext(),"Login Cancelled", Toast.LENGTH_SHORT).show();
}
#Override
public void onError(FacebookException e) {
Toast.makeText(getBaseContext(),"Problem connecting to Facebook", Toast.LENGTH_SHORT).show();
}
});
And the request for user profile:
public void requestUserProfile(LoginResult loginResult){
GraphRequest.newMeRequest(
loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject me, GraphResponse response) {
if (response.getError() != null) {
// handle error
} else {
try {
String email = response.getJSONObject().get("email").toString();
Log.e("Result", email);
} catch (JSONException e) {
e.printStackTrace();
}
String id = me.optString("id");
// send email and id to your web server
Log.e("Result1", response.getRawResponse());
Log.e("Result", me.toString());
}
}
}).executeAsync();
}
The JSON response returns only the ID and full name of my account but doesn't include the email. Did I missed out something?
You need to ask for parameters to facebook in order to get your data. Here I post my function where I get the facebook data. The key is in this line:
parameters.putString("fields", "id, first_name, last_name, email,gender, birthday, location"); // Parámetros que pedimos a facebook
btnLoginFb.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
System.out.println("onSuccess");
progressDialog = new ProgressDialog(LoginActivity.this);
progressDialog.setMessage("Procesando datos...");
progressDialog.show();
String accessToken = loginResult.getAccessToken().getToken();
Log.i("accessToken", accessToken);
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.i("LoginActivity", response.toString());
// Get facebook data from login
Bundle bFacebookData = getFacebookData(object);
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id, first_name, last_name, email,gender, birthday, location"); // Parámetros que pedimos a facebook
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
System.out.println("onCancel");
}
#Override
public void onError(FacebookException exception) {
System.out.println("onError");
Log.v("LoginActivity", exception.getCause().toString());
}
});
private Bundle getFacebookData(JSONObject object) {
try {
Bundle bundle = new Bundle();
String id = object.getString("id");
try {
URL profile_pic = new URL("https://graph.facebook.com/" + id + "/picture?width=200&height=150");
Log.i("profile_pic", profile_pic + "");
bundle.putString("profile_pic", profile_pic.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
bundle.putString("idFacebook", id);
if (object.has("first_name"))
bundle.putString("first_name", object.getString("first_name"));
if (object.has("last_name"))
bundle.putString("last_name", object.getString("last_name"));
if (object.has("email"))
bundle.putString("email", object.getString("email"));
if (object.has("gender"))
bundle.putString("gender", object.getString("gender"));
if (object.has("birthday"))
bundle.putString("birthday", object.getString("birthday"));
if (object.has("location"))
bundle.putString("location", object.getJSONObject("location").getString("name"));
return bundle;
}
catch(JSONException e) {
Log.d(TAG,"Error parsing JSON");
}
return null;
}
Instead of getting the value of the graphResponse, access the email using the JSONObject me
userEmail = jsonObject.getString("email");
Hope it helps you
/*** setupFacebook stuff like make login with facebook and get the userId,Name and Email*/
private void setupFacebookStuff() {
Log.e(TAG, "key hash= " + Utils.getKeyHash(SplashActivity.this, getPackageName()));
// This should normally be on your application class
FacebookSdk.sdkInitialize(SplashActivity.this);
accessTokenTracker = new AccessTokenTracker() {
#Override
protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) {
currentAccessToken.getToken();
}
};
loginManager = LoginManager.getInstance();
callbackManager = CallbackManager.Factory.create();
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
preference.setUserLogin(true);
final GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
Log.e("id", "" + object);
if (object.has(getString(R.string.fbParamId))) {
final String userId = object.optString(getString(R.string.fbParamId));
final String userPicture = "https://graph.facebook.com/" + object.optString(getString(R.string.fbParamId)) + "/picture?type=large";
preference.setUserId(userId);
preference.setUserPictureUrl(userPicture);
}
if (object.has(getString(R.string.fbParamUserName))) {
final String userName = object.optString(getString(R.string.fbParamUserName));
preference.setUserName(userName);
}
if (object.has(getString(R.string.fbParamEmail))) {
final String userEmail = object.optString(getString(R.string.fbParamEmail));
preference.setUserName(userEmail);
Log.e("useremail", userEmail);
}
callMainActivity(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
final Bundle parameters = new Bundle();
parameters.putString("fields", "name,email,id");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
Toast.makeText(getBaseContext(), "Login Cancelled", Toast.LENGTH_SHORT).show();
}
#Override
public void onError(FacebookException error) {
Toast.makeText(getBaseContext(), "Problem connecting to Facebook", Toast.LENGTH_SHORT).show();
Log.e(TAG, "Facebook login error " + error);
}
});
}
You can also use GraphResponse object to get the values
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) {
Log.v("LoginActivity", response.toString());
try {
// Application code
String email = response.getJSONObject().getString("email");
txtStatus.setText("Login Success \n" + email);
}catch(Exception e){
e.printStackTrace();;
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender,birthday");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel()
{
txtStatus.setText("==============Login Cancelled=============");
}
#Override
public void onError(FacebookException exception)
{
txtStatus.setText("==============Login Error=================");
exception.printStackTrace();
}
});
Putting this code:
btnLoginFb.setReadPermissions(Arrays.asList("email"));
before
RegisterCallback
should solve the problem.
I guess getting email permissions can help..
LoginManager.getInstance().logInWithReadPermissions(
fragmentOrActivity,
Arrays.asList("email"));
Information
If you are giving any permission to get an email address.
then, Facebook can not every time gives you email address or some other details.
When, Facebook user is not signup with his email-address then Facebook can't provide you his email address.
If user is login with Facebook using email address then Facebook will provides email to you.
Facebook SDK provide only public details.
check a login with Facebook using email-address and also with phone number through.