How to get user Gender and birthday from facebook in android - java

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.

Related

Login to Firebase using phone returns null pointer

I'm trying to follow the tutorial from Firebase to allow users to login using their phone number. I've watched a tutorial video. All my code looks correct, but when I try it on my test device I receive a null pointer error.
at com.google.android.gms.common.internal.Preconditions.checkNotNull(Unknown Source)
at com.google.firebase.auth.PhoneAuthProvider.verifyPhoneNumber(Unknown Source)
at studios.p9p.chatomatic.chat_o_matic.PhoneLogin.CheckPhoneNumber(PhoneLogin.java:92)
at studios.p9p.chatomatic.chat_o_matic.PhoneLogin.access$000(PhoneLogin.java:29)
at studios.p9p.chatomatic.chat_o_matic.PhoneLogin$1.onClick(PhoneLogin.java:52)
My code for the phone login is as follows:
private EditText et_check_phone_number;
private EditText et_verify_code;
private Button btn_phone;
private Button btn_verify;
private String getPhoneNumber, getVerifactionCode;
private String mVerificationId = "";
private FirebaseAuth mAuth;
private FirebaseDatabase db;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mcallBacks;
private PhoneAuthProvider.ForceResendingToken mResendToken;
private ProgressDialog mloading;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone_login);
mAuth = FirebaseAuth.getInstance();
initVariables();
btn_phone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CheckPhoneNumber();
}
});
btn_verify.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
VerifyPhoneNumber();
}
});
}
private void initVariables() {
et_check_phone_number = findViewById(R.id.et_phonenumber);
et_verify_code = findViewById(R.id.etvarifaction);
btn_phone = findViewById(R.id.btn_phone_login);
btn_verify = findViewById(R.id.btn_phone_verify);
mloading = new ProgressDialog(this);
}
private void CheckPhoneNumber() {
getPhoneNumber = et_check_phone_number.getText().toString();
if (TextUtils.isEmpty(getPhoneNumber))
{
Toast.makeText(this, "Phone Number Field Cant Be Empty...", Toast.LENGTH_SHORT).show();
} else{
mloading.setTitle("Checking Your Phone Number");
mloading.setMessage("It Gonna Take A Second...");
mloading.setCanceledOnTouchOutside(false);
mloading.setIcon(R.mipmap.ic_launcher);
mloading.show();
PhoneAuthProvider.getInstance().verifyPhoneNumber(
getPhoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mcallBacks);
}
}
mcallBacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
signInWithPhoneAuthCredential(phoneAuthCredential);
}
#Override
public void onVerificationFailed(FirebaseException e) {
Toast.makeText(PhoneLogin.this, "Wrong Or Invalid Phone Number...", Toast.LENGTH_SHORT).show();
btn_phone.setVisibility(View.VISIBLE);
et_check_phone_number.setVisibility(View.VISIBLE);
et_verify_code.setVisibility(View.INVISIBLE);
btn_verify.setVisibility(View.INVISIBLE);
if (e instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(getBaseContext(), "Invalid Request " + e.toString(), Toast.LENGTH_SHORT).show();
} else if (e instanceof FirebaseTooManyRequestsException) {
Toast.makeText(getBaseContext(), "The SMS quota for the project has been exceeded " + e.toString(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
// Save verification ID and resending token so we can use them later
mVerificationId = verificationId;
mResendToken = token;
Toast.makeText(PhoneLogin.this, "Code Sent Please Check Your SMS...", Toast.LENGTH_SHORT).show();
btn_phone.setVisibility(View.INVISIBLE);
et_check_phone_number.setVisibility(View.INVISIBLE);
et_verify_code.setVisibility(View.VISIBLE);
btn_verify.setVisibility(View.VISIBLE);
}
};
}
private void VerifyPhoneNumber() {
getVerifactionCode = et_verify_code.getText().toString();
if (TextUtils.isEmpty(getVerifactionCode)){
Toast.makeText(this, "Please Enter The Code Sent To Your SMS...", Toast.LENGTH_SHORT).show();
}else{
mloading.setTitle("Checking Your Verification code ");
mloading.setMessage("Ill Be Back In A Jiffy...");
mloading.setCanceledOnTouchOutside(false);
mloading.setIcon(R.mipmap.ic_launcher);
mloading.show();
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, getVerifactionCode);
signInWithPhoneAuthCredential(credential);
}
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
mloading.dismiss();
Toast.makeText(PhoneLogin.this, "Login Successful...", Toast.LENGTH_SHORT).show();
Intent phoneloginIntent =new Intent (getBaseContext(),Home_Screen.class);
phoneloginIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(phoneloginIntent);
finish();
} else {
String mesage = task.getException().toString();
Toast.makeText(PhoneLogin.this, "Error: " + mesage, Toast.LENGTH_SHORT).show();
}
}
});
}
The "+44" I added trying to see if I was entering the wrong phone number. I tried it by adding the +44 manually into the edit text of the app first and that gave the same error.
Edit
So I've removed the line inside the Auth provider that asked if the number was larger than 9 digits as it wasn't working. Also I ran a log to see if it capturing the phone number correctly.
Log.i("Verify_Phone_Number",getPhoneNumber);
2019-07-16 14:15:30.585 32055-32055/studios.p9p.chatomatic.chat_o_matic I/Verify_Phone_Number: +447******100 and it returns correctly
Edit 2
So on further testing if I click btn_phone before entering the phone number it works correctly, but if I simply add the phone number to the edit test first then press thebtn_phone it crashes with the above message in logcat.
As per Firebase Docs you have to pass the Number with Country Code :
E.g.
phone number = +919090909090
See Following Picture :
As you can see even testing number needs country code with them.
When your app crashes it means Firebase PhoneAuthProvider.getInstance().verifyPhoneNumber() not getting the number with country code.
You can try this following code before passing to if condition :
if (et_check_phone_number.getText().toString().startsWith("+44"){
getPhoneNumber = et_check_phone_number.getText().toString();
}else{
getPhoneNumber = "+44"+et_check_phone_number.getText().toString();
}
Above Code will check whether user put prefix of your country code or not.
Ok so the way i solved this problem was to move the mcallbacks to the on create section of code. as shown below
setContentView(R.layout.activity_phone__login);
mAuth = FirebaseAuth.getInstance();
InitVariables();
AddPhoneNumberButtons();
mcallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
signInWithPhoneAuthCredential(phoneAuthCredential);
}
#Override
public void onVerificationFailed(FirebaseException e) {
Toast.makeText(getBaseContext(), "Wrong Or Invalid Phone Number...", Toast.LENGTH_SHORT).show();
AddPhoneNumberButtons();
if (e instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(getBaseContext(), "Invalid Request " + e.toString(), Toast.LENGTH_SHORT).show();
} else if (e instanceof FirebaseTooManyRequestsException) {
Toast.makeText(getBaseContext(), "The SMS quota for the project has been exceeded " + e.toString(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
// Save verification ID and resending token so we can use them later
verificationid = verificationId;
mresendtoken = token;
Toast.makeText(getBaseContext(), "Code Sent Please Check Your SMS...", Toast.LENGTH_SHORT).show();
AddVerifyButtons();
}
};

Facebook API doesn't return email

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);
}

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 after login get user information

I am trying to get the user information after login with facebook.
callbackManager = CallbackManager.Factory.create();
loginButton = (LoginButton) findViewById(R.id.login_button);
loginButton.setReadPermissions("user_birthday", "email");
final Context contextM = this.getApplicationContext();
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
String firstName = Profile.getCurrentProfile().getFirstName();
String lastName = Profile.getCurrentProfile().getLastName();
String url = Profile.getCurrentProfile().getProfilePictureUri(100, 100).toString();
final ImageView mImageView = (ImageView) findViewById(R.id.imageView);
ImageRequest request = new ImageRequest(url,
new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap bitmap) {
mImageView.setImageBitmap(bitmap);
}
}, 0, 0, null,
new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
}
});
MySingleton.getInstance(contextM).addToRequestQueue(request);
}
and this is the error I get :
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String com.facebook.Profile.getFirstName()' on a null
object reference
I have accessed results as follows using graph request. check if this helps you
LoginManager.getInstance().registerCallback(callbackManager,
new FacebookCallback<LoginResult>(){
#Override
public void onSuccess(final LoginResult loginResult){
GraphRequest request=GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback(){
#Override
public void onCompleted(
JSONObject object,
GraphResponse response){
if(response.getError()!=null){
// handle error
}else{
//**access details as follows**
String email=object.optString("email");
String first_name=object.optString("first_name");
String last_name=object.optString("last_name");
}
});
Bundle parameters=new Bundle();
parameters.putString("fields","id,first_name,last_name,email,gender,birthday");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel(){
//Toast.makeText(context, "Something went wrong. Please try again",
// Toast.LENGTH_SHORT).show();
}
#Override
public void onError(FacebookException exception){
//Toast.makeText(getActivity(), "Error", Toast.LENGTH_SHORT).show();
exception.printStackTrace();
}
});
It seems you have missed public_profile permission which alllows you to get both first_name as well as last name.
Just check what all permission you are granted using getRecentlyGrantedPermissions().

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));
}
});

Categories