I am having the following code that signin the user to facebook through my app. I am getting user.getproperty("email") as null first time. when i run the app second time i am getting the value. below is my code.
private void loginToFb() {
final Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(
LandingPageActivity.this, Arrays.asList(
"user_location", "user_birthday",
"user_likes", "email"));
Session.openActiveSession(this, true, new Session.StatusCallback() {
// callback when session changes state
@Override
public void call(Session session, SessionState state,
Exception exception) {
if (session.isOpened()) {
session.requestNewReadPermissions(newPermissionsRequest);
// make request to the /me API
Request request = Request.newMeRequest(session,
new Request.GraphUserCallback() {
// callback after Graph API response with user
// object
@Override
public void onCompleted(GraphUser user,
Response response) {
if (user != null) {
fetchUserFbDetails(user);
}
}
});
Request.executeBatchAsync(request);
}
}
});
}
The issue is that you're requesting new permissions INSIDE the status callback, but then you're making the meRequest immediately, before the new permissions request completes (all permissions and session open requests are asynchronous).
Since you're asking for only read permissions, there's no need to make a separate permission request, you can do it all in one go. Something like:
Session.OpenRequest openRequest = new Session.OpenRequest(LandingPageActivity.this);
openRequest.setPermissions(Arrays.asList...);
openRequest.setCallback(new Session.StatusCallback() {
// callback when session changes state
@Override
public void call(Session session, SessionState state,
Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request request = Request.newMeRequest(session,
new Request.GraphUserCallback() {
// callback after Graph API response with user
// object
@Override
public void onCompleted(GraphUser user,
Response response) {
if (user != null) {
fetchUserFbDetails(user);
}
}
});
request.executeAsync();
}
});
Session session = new Session(LandingPageActivity.this);
Session.setActiveSession(session);
session.openForRead(openRequest);
Instead of managing sessions yourself, you should use Facebook's LoginButton
and the UiLifecycleHelper
.
1) Declare a LoginButton in your UI:
<!-- FACEBOOK LOGIN -->
<com.facebook.widget.LoginButton
android:id="@+id/facebookLoginBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true" />
2) Create a LoginFragment
and declare a private member:
private UiLifecycleHelper mFacebookLifecycleHelper;
3) In Fragment's onCreate()
method, initialize the LoginButton and add a hook to get user's info:
LoginButton facebookLoginButton = (LoginButton) view.findViewById(R.id.facebookLoginBtn);
facebookLoginButton.setFragment(this);
// Intercept the facebook user returned from login
facebookLoginButton.setUserInfoChangedCallback(new LoginButton.UserInfoChangedCallback() {
@Override
public void onUserInfoFetched(GraphUser user) {
mFacebookUser = user;
if (user != null) {
LogUtils.LOGFB(TAG, "Got a Facebook user: " + user.getFirstName() +
" " + user.getLastName() + ", email: " + user.getProperty("email"));
}
else {
LogUtils.LOGFB(TAG, "No Facebook user");
}
}
});
// Set extra read permissions
facebookLoginButton.setReadPermissions(Arrays.asList(
"email", "user_birthday", ...));
4) Create a callback to listen for Facebook session state changes:
// Listen for changes in Facebook session state
private Session.StatusCallback callback = new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
// Respond to Facebook session state changes
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
LogUtils.LOGFB(TAG, "Logged in using facebook");
LogUtils.LOGFB(TAG, "Access Token: " + session.getAccessToken());
// TODO: display authenticated UI
} else if (state.isClosed()) {
LogUtils.LOGFB(TAG, "Logged out from facebook");
// TODO: display the non-authenticated UI
}
}
5) Then make sure you call the lifecycleHelper for all the lifecycle changes of your fragment:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Creates the Facebook session and opens it automatically if a cached token is available.
mFacebookLifecycleHelper = new UiLifecycleHelper(getActivity(), callback);
mFacebookLifecycleHelper.onCreate(savedInstanceState);
...
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mFacebookLifecycleHelper.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onResume() {
super.onResume();
mFacebookLifecycleHelper.onResume();
}
@Override
public void onPause() {
super.onPause();
mFacebookLifecycleHelper.onPause();
}
@Override
public void onDestroy() {
mFacebookLifecycleHelper.onDestroy();
super.onDestroy();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mFacebookLifecycleHelper.onSaveInstanceState(outState);
}
Try this code.
String email = user.getProperty("email").toString();
String safeEmail = user.asMap().get("email").toString();