Android Facebook - get null profile - android

First time with Facebook SDK. I can't get users profile. Its always null. What's wrong?
btnFbWidget = (LoginButton) findViewById(R.id.btnFbWidget);
btnFbWidget.setReadPermissions("public_profile");
// Callback registration
btnFbWidget.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Profile profile = Profile.getCurrentProfile();
if (profile != null)
Toast.makeText(getApplicationContext(), "LogIN as " + profile.getName(), Toast.LENGTH_SHORT).show();
else
Toast.makeText(getApplicationContext(), "nulll", Toast.LENGTH_SHORT).show();
}
/*...*/
});

use this method also,.....
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}

Try with this method.
Initialize facebook SDK firstly.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//init facebook sdk and
FacebookSdk.sdkInitialize(getApplicationContext());
setContentView(R.layout.activity_main);
//instantiate callbacks manager
mCallbackManager = CallbackManager.Factory.create();
btnFbWidget=(LoginButton)findViewById(R.id.login_button);
btnFbWidget.registerCallback(mCallbackManager, this);
btnFbWidget.setReadPermissions(Arrays.asList("user_status","email"));
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//manage login result
mCallbackManager.onActivityResult(requestCode, resultCode, data);
}
public void onSuccess(LoginResult loginResults) {
Toast.makeText(getApplicationContext(), "Success ",
Toast.LENGTH_LONG).show();
}
public void onCancel() {
}
public void onError(FacebookException e) {
}
And then to get the User Profile use this method.
private static String uid,email;
public void getUserProfile() {
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(
JSONObject object,
GraphResponse response) {
// Application code
Log.v("LoginActivity", response.toString());
try {
//and fill them here like so.
uid = object.getString("id");
email = object.getString("email")
} catch (JSONException e) {
e.printStackTrace();
}
getGroups();
}
});
// If you want to pass data to other activity.
Bundle parameters = new Bundle();
parameters.putString("userdata", "email");
request.setParameters(parameters);
request.executeAsync();
}
And do call this method getUserProfile() in your on create.
EDIT 1 :
Change in read permissions.
btnFbWidget.setReadPermissions(Arrays.asList("public_profile", "email", "user_birthday", "user_friends"));
And accordingly you can get further information like.
String email = object.getString("email");
String birthday = object.getString("birthday");

Related

Android Facebook Registercallback not called

I am using facebook login into my application. Now I am facing one strange issue in my project LoginManager.getInstance().registerCallback not getting called.
I am using following codes:
FacebookSdk.sdkInitialize(getActivity());//It showing as deprecated now
AppEventsLogger.activateApp(getActivity());//It showing as deprecated now
callbackManager = CallbackManager.Factory.create();
muvattapuzha
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
System.out.println("eeeee");
// App code
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(
JSONObject object,
GraphResponse response) {
// Application code not called
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,link,birthday,gender");
request.setParameters(parameters);
request.executeAsync();
}
OnActivity result method:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
callbackManager.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}
Note: I am using with Activity->fragment-> fragment.
Activity onResult method like
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
for (Fragment fragment1 : fragment.getChildFragmentManager().getFragments()) {
fragment1.onActivityResult(requestCode, resultCode, data);
Log.d("Activity", "ON RESULT CALLED");
}
}
} catch (Exception e) {
Log.d("ERROR", e.toString());
}
}
What could be the issue here?
Use this code this is working fine for me.
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/app_name"
android:theme="#android:style/Theme.Translucent.NoTitleBar" />
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//requestWindowFeature(Window.FEATURE_NO_TITLE);
callbackManager = CallbackManager.Factory.create();
FacebookSdk.sdkInitialize(LoginMainActivity.this);
setContentView(R.layout.activity_login_main);
loginButton = findViewById(R.id.activity_main_btn_login);
loginButton.setBackgroundResource(R.drawable.fb_rounded_broder);
loginButton.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
loginButton.setCompoundDrawablePadding(0);
loginButton.setText("");
loginButton.setReadPermissions(Arrays.asList(new String[]{"email", "user_birthday", "user_hometown"}));
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.d(TAG, "User login successfully");
getProfile();
}
#Override
public void onCancel() {
// App code
Log.d(TAG, "User cancel login");
}
#Override
public void onError(FacebookException exception) {
// App code
Log.d(TAG, "Problem for login");
}
});
public void getProfile() {
try {
accessToken = AccessToken.getCurrentAccessToken();
GraphRequest request = GraphRequest.newMeRequest(
accessToken,
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(
JSONObject object,
GraphResponse response) {
Log.d(TAG, "Graph Object :" + object);
try {
String[] splitStr = object.getString("name").split("\\s+");
FBFirstname = splitStr[0];
FBLastName = splitStr[1];
FBEmail = object.getString("email");
FBUUID = object.getString("id");
Log.e(TAG, "firstnamev: " + splitStr[0]);
Log.e(TAG, "last name: " + splitStr[1]);
Log.e(TAG, "Email id : " + object.getString("email"));
Log.e(TAG, "ID :" + object.getString("id"));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,link,birthday,gender,email");
request.setParameters(parameters);
request.executeAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from
{
callbackManager.onActivityResult(requestCode, resultCode, data);
}
}

Dismiss facebook login dialog android

I've integrated facebook sdk v-4 with my android app. Here I've worked facebook login in 2 activities.
1) In one activity fb login is done via LoginButton. Where after successful login the fb login dialog is dismissed by facebook sdk automatically.
code:
fbLoginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
ProfileTracker profileTracker;
#Override
public void onSuccess(LoginResult loginResult) {
Logger.d("FBLOGIN", "login successful. User ID: "
+ loginResult.getAccessToken().getUserId()
+ "\n" +
"Auth Token: "
+ loginResult.getAccessToken().getToken());
com.facebook.Profile fbProfile = com.facebook.Profile.getCurrentProfile();
if (fbProfile == null) {
profileTracker = new ProfileTracker() {
#Override
protected void onCurrentProfileChanged(com.facebook.Profile oldProfile, com.facebook.Profile currentProfile) {
profileTracker.stopTracking();
doTaskWithFbProfile(currentProfile);
}
};
profileTracker.startTracking();
} else {
doTaskWithFbProfile(fbProfile);
}
}
#Override
public void onCancel() {
Logger.d(TAG, "fb Login attempt canceled.");
}
#Override
public void onError(FacebookException e) {
Logger.e(TAG, "fb Login attempt failed." + e);
Toast.makeText(LoginActivity.this,R.string.str_please_check_your_internet_connection,Toast.LENGTH_LONG).show();
}
});
private void doTaskWithFbProfile(com.facebook.Profile fbProfile) {
Logger.d("FBLOGIN", "id - " + fbProfile.getId());
Logger.d("FBLOGIN", "name - " + fbProfile.getName());
Logger.d("FBLOGIN", "pic - " + fbProfile.getProfilePictureUri(150, 150));
com.android.circlecare.models.common.Profile profile = new com.android.circlecare.models.common.Profile();
profile.setFBID(fbProfile.getId());
profile.setName(fbProfile.getName());
profile.setProfilePhoto(fbProfile.getProfilePictureUri(150, 150).toString());
Intent intent = new Intent(this, LoginWithFacebookActivity.class);
intent.putExtra(LoginWithFacebookActivity.EXTRA_PROFILE, profile);
startActivity(intent);
finish();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
callbackManager.onActivityResult(requestCode, resultCode, data);
}
2)On the other hand I used LoginManager to log in to fb. Where after successful login the login dialog does not get dismissed, instead it stays in front and again after login the dialog doesn't go.
code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(this.getApplicationContext());
mFacebookCallback = new FacebookCallback<LoginResult>() {
ProfileTracker profileTracker;
#Override
public void onSuccess(LoginResult loginResult) {
Profile fbProfile = Profile.getCurrentProfile();
if (fbProfile == null) {
profileTracker = new ProfileTracker() {
#Override
protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) {
profileTracker.stopTracking();
getAllFriends();
}
};
profileTracker.startTracking();
} else {
getAllFriends();
}
}
#Override
public void onCancel() {
Logger.d(TAG, "fb Login attempt canceled.");
}
#Override
public void onError(FacebookException error) {
Logger.d(TAG, "Error : " + error.getMessage());
finish();
}
};
callbackManager = CallbackManager.Factory.create();
if (hasAccess)
getAllFriends();
else
loginWorks();
}
private void loginWorks() {
loginManager = LoginManager.getInstance();
loginManager.registerCallback(callbackManager, mFacebookCallback);
ArrayList<String> publishPermission = new ArrayList<>();
publishPermission.add("publish_pages");
publishPermission.add("publish_actions");
loginManager.logInWithPublishPermissions(this, publishPermission);
ArrayList<String> readPermission = new ArrayList<>();
readPermission.add("user_friends");
readPermission.add("public_profile");
readPermission.add("user_about_me");
loginManager.logInWithReadPermissions(this, readPermission);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
I've used almost same codes in both the cases, but I wonder why login dialog isn't get dismissed when working with LoginManager.
Can any one point out the problem or is there any api to dismiss fb login dialog(web view).
In your loginWorks() method, you're literally calling login twice, which is probably actually showing 2 different login screens, and why it looks like the dialog is not dismissing after you finish one of them. Try removing the loginWithPublishPermissions call, and put it in the callback from the read permissions call if you really need it.

FacebookCallback not being executed

I have an app in which I implemented facebook login which was working last time I checked. For some reason, now, after I click the button nothing happens.
My onCreate()
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getActivity());
mCallbackManager = CallbackManager.Factory.create();
}
my loginButton
loginButton = (LoginButton) view.findViewById(R.id.login_button);
loginButton.setReadPermissions("user_friends");
loginButton.setFragment(this);
loginButton.registerCallback(mCallbackManager, mFacebookCallback);
my onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("askj","Callback called with requestCode "+requestCode+" + resultCode "+resultCode);
mCallbackManager.onActivityResult(requestCode, resultCode, data);
}
my mFacebookCallback
private FacebookCallback<LoginResult> mFacebookCallback = new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.d("askj", "onSuccess");
AccessToken accessToken = loginResult.getAccessToken();
Profile profile = Profile.getCurrentProfile();
Log.d("askj", "profile " + profile.toString());
if (profile != null) {
Intent upanel = new Intent(getActivity(), AfterLogin.class);
upanel.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(upanel);
}
}
#Override
public void onCancel() {
Log.d("askj", "onCancel");
}
#Override
public void onError(FacebookException e) {
Log.d("askj", "onError " + e);
}
};
This is what is being printed in logCat once the button is clicked:
Callback called with requestCode 129742 + resultCode -1
I don't get anything from mFacebookCallback in the console.
Edit: How can I add a specific requestCode to this callback ?
Edit2: For anyone having this problem, I solved it by removing loginButton.setFragment(this);. I still have this question though How can I add a specific requestCode to this callback ?

Facebook Login Not Returning User access_token

This is my first post, so please let me know if I'm not abiding by the community rules.
Now to the problem! I've been trying to setup the Facebook login process for an app and I've gotten as far as adding a GUI element (the built-in Facebook login button), and having the button go ahead and ask for a user/pass, granting the app access to the user's account. The problem I'm facing is that when using the following code to get a callback value from the app I receive nothing (no value being printed). Right now I'm printing to LogCat arbitrary values, however as soon as printing works, I look to access the user access_token and other information (which didn't initially work). Any help appreciated!
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connect_accounts);
Log.i("fromMe", "test1");
FacebookSdk.sdkInitialize(this.getApplicationContext());
callbackManager = CallbackManager.Factory.create();
LoginButton loginButton = (LoginButton)findViewById(R.id.login_button);
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>(){
public void onSuccess(LoginResult loginResult) {
Log.i("fromMe", "1");
}
public void onCancel() {
Log.i("fromMe", "2");
}
public void onError(FacebookException exception) {
Log.i("fromMe", "3");
}
});
}
if Log.i("fromMe", "1");work so you can call :
AccessToken accessToken = loginResult.getAccessToken();
in your onSuccess().
And in onActivityResult(int requestCode, int resultCode, Intent data)
add :
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
I never used the built-in facebook button ,instead i used the normal button with a click a listener. and i call this method in the onClick().
myButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
//Starting facebook signIN
startFbSignIn();
}
});
startFbSignIn();
private void startFbSignIn() {
List<String> permissions = new ArrayList<>();
permissions.add("email");
Session.openActiveSession(this, true, permissions, new Session.StatusCallback() {
#Override
public void call(final Session session, SessionState sessionState, Exception e) {
Log.d("X", "Call Called");
if (session.isOpened()) {
Log.d("X", "SessionOpened" + session.getAccessToken());
//Showing some loading
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser graphUser, Response response) {
//FACEBOOOK SIGNIN SUCCESS
Log.i("X", "Facebook Login Success");
//Log
Log.d("X", "GRAPH USER:" + graphUser.toString());
String name = graphUser.getName();
//.....
}
}).executeAsync();
} else {
Log.d("X", "SessioNOTopened");
}
}
});
}
The above method successfully working for me and your onActivityResult() must look something like this
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//Facebook Session Manager
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
Probably cause of a bug in the facebook SDK you cannot directly get the accessToken. We need to create an accessToken tracker and then get the accessToken
private AccessTokenTracker accessTokenTracker;
accessTokenTracker = new AccessTokenTracker() {
#Override
protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken newAccessToken) {
try {
if (newAccessToken.getToken() != null) {
facebookAccessToken = newAccessToken.getToken();
//this is your accessToken here
}
else if (oldAccessToken.getToken() != null) {
facebookAccessToken = oldAccessToken.getToken();
//this is your accessToken here
}else {
Toast.makeText(getBaseContext(), "Facebook Login Failed", Toast.LENGTH_LONG).show();
}
if(oldAccessToken.getToken()!=null)
Log.e("old", oldAccessToken.getToken());
}catch (Exception e){
e.printStackTrace();
}
}
};
once this is successfully done, overide the onStop method of the activity and make sure you stoptracking the accessToken there.
accessTokenTracker.stopTracking();

How to re-ask declined permissions in Facebook SDK 4.0 (android)

I checked below. It is very similar but it is not same my problem.
How to re-request permissions in Facebook SDK 4.0
I got permissions in this code.
LoginManager.getInstance().logInWithReadPermissions(*fragment*, "user_friends");
If a user reject "user_friends" permission, I can't re-ask "user_friends" permissions above code. Because automatically rejected on next authentication.
What actions should I do to get "user_friends" programmatically?
its simple just use
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Log.e(TAG, "LoginManager FacebookCallback onSuccess");
if (loginResult.getAccessToken() != null) {
Set<String> deniedPermissions = loginResult.getRecentlyDeniedPermissions();
if (deniedPermissions.contains("user_friends")) {
LoginManager.getInstance().logInWithReadPermissions(MainActivity.this, Arrays.asList("user_friends"));
}
}
}
#Override
public void onCancel() {
Log.e(TAG, "LoginManager FacebookCallback onCancel");
}
#Override
public void onError(FacebookException e) {
Log.e(TAG, "LoginManager FacebookCallback onError");
}
});
and do not forget to initialize fb SDK before you call setContentView(R.layout.main)
i.e
// Create callback manager to handle login response
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fb = (ImageView) findViewById(R.id.authFacebook);
setFacebookData(savedInstanceState);
fb.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
LoginManager.getInstance().logInWithReadPermissions(MainActivity.this, Arrays.asList("public_profile", "email"));
}
});
}
private void setFacebookData(Bundle savedInstanceState) {
FacebookSdk.sdkInitialize(MainActivity.this);
callbackManager = CallbackManager.Factory.create();
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult result) {
Log.i("LoginActivity","onSuccess Facebook Login"+result);
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject jsonObject, GraphResponse response) {
Log.d("","onCompleted jsonObject: "+jsonObject);
Log.d("","onCompleted response: "+response);
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,link,cover,email");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
// TODO Auto-generated method stub
}
#Override
public void onError(FacebookException e) {
// TODO Auto-generated method stub
Log.e("LoginActivity","ERROR: "+e.getMessage());
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("FbLogin", "Result Code is = " + resultCode +"");
callbackManager.onActivityResult(requestCode, resultCode, data);
}
In Manifest File add these lines
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/app_id" />
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="com.facebook.app.FacebookContentProvider355198514515820"
android:exported="true" />
<receiver android:name="laddu.fbexample.HelloFacebookBroadcastReceiver" >
<intent-filter>
<action android:name="com.facebook.platform.AppCallResultBroadcast" />
</intent-filter>
</receiver>
Solution by user2403096 works well, but I've encountered some problem and spent some time to resolve it. If User revoked some permission through console or somehow else and you need it in your app during login (e.g. I need email permission) I use code by user2403096 :
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
if (loginResult.getRecentlyDeniedPermissions().contains("email")) {
LoginManager.getInstance().logInWithReadPermissions(
this, (Collections.singletonList("email")));
} else {
performGraphRequest();
}
}
#Override
public void onCancel() {
Log.e(TAG, "LoginManager FacebookCallback onCancel");
}
#Override
public void onError(FacebookException e) {
Log.e(TAG, "LoginManager FacebookCallback onError");
}
});
performGraprhRequest() just obtains profile info with GraphRequest.newMeRequest(token, callback). So when you re-requesting permission there will be callback into onActivityResult but onSuccess(), onCancel() or onError() will NOT be called again. My approach is:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
boolean processed = mCallbackManager.onActivityResult(requestCode, resultCode, data);
if (!processed) {
performGraphRequest();
}
}
If you login into facebook and enter your credentials - onActivityResult will be processed by CallbackManager and will return true. CallbackManager under the hood checks whether your current AccessToken null or not and if you already logged in and then you re-ask permission - you will have token and callbackManager.onActivityResult return false. Then you can invoke performGraphRequest and login user into your app.
Just an improvement to #Naveedumar 's answer
You can also do
LoginManager.getInstance()
.logInWithReadPermissions(MainActivity.this,
new ArrayList<String>(AccessToken.getCurrentAccessToken().getDeclinedPermissions()) );

Categories

Resources