i am new to facebook development on android. My target is to get the list of page names liked by a user. I am using the fallowing code for that.
I want to make sure that i am using the latest facebook sdk and none of the classes or methods i am using are deprecated
ArrayList<String> permissions = new ArrayList<String>();
permissions.add("user_likes");
loginButton.clearPermissions();
loginButton.setReadPermissions(permissions);
loginButton.setUserInfoChangedCallback(new LoginButton.UserInfoChangedCallback() {
#Override
public void onUserInfoFetched(GraphUser user) {
if(user != null)
{
Log.d(TAG,"User login successful:"+user.getProperty("favorite_teams"));
Session session = Session.getActiveSession();
if(session !=null && session.isOpened())
{
if(session.getPermissions().contains("user_likes"))
{
requestForPageLikes = new Request(session, "https://graph.facebook.com/me/likes");
requestForPageLikes.setCallback(new Request.Callback() {
#Override
public void onCompleted(Response response) {
GraphObject go = response.getGraphObject();
JSONObject jso = go.getInnerJSONObject();
Log.d(TAG,"Facebook response:"+jso.toString());
}
});
Request.executeAndWait(requestForPageLikes);
}
}
}
}
}
The above request is working fine and i am getting the response code as 200, which is OK.
but the log message is printing as
Facebook response:{"id":"https://graph.facebook.com/me/likes"}
I am sure that there are pages which the user has liked, and my app is configured well in developers.facebook.com and as we see in the above code i have the permission user_likes which is required to read the like pages.
I am heavily stuck with this issue. Any help would be really appreciated.
Related
Recently, Facebook released SDK 4 with new and cool updates. I tried to switch into SDK4 to use new features, however, I am struggling with the Login feature of Facebook.
So far, to log out Facebook programmatically, I used :
Session session = Session.getActiveSession();
session.closeAndClearTokenInformation();
But SDK4 seems not to support Session anymore, and in official docs, they mention:
There are two ways to implement Facebook login on Android:
LoginButton class - Which provides a button you can add to your UI. It follows the current access token and can log people in and out.
Well, seems there's no way to log out Facebook programmatically except using LoginButton.
Anyone have any idea, please share it here.
You can use LoginManager.getInstance().logOut();, even if you use LoginButton because
This UI element wraps functionality available in the LoginManager.
EDIT:
Just to mention that this works for Facebook SDK v4. I don't know if they will change it in the future.
#as batoutofhell mention, don't forget to put FacebookSdk.sdkInitialize(getApplicationContext()); to initialize the facebook sdk. Please see here for the details.
SDK4, if you want to completely de-couple, make sure you also remove the app from the user's facebook account. This method disconnects the user completely:
public void disconnectFromFacebook() {
if (AccessToken.getCurrentAccessToken() == null) {
return; // already logged out
}
new GraphRequest(AccessToken.getCurrentAccessToken(), "/me/permissions/", null, HttpMethod.DELETE, new GraphRequest
.Callback() {
#Override
public void onCompleted(GraphResponse graphResponse) {
LoginManager.getInstance().logOut();
}
}).executeAsync();
}
You can use LoginManager.logOut()
Check out https://developers.facebook.com/docs/reference/android/current/class/LoginManager/
To handle it with the loginButton:
//Check if user is currently logged in
if (AccessToken.getCurrentAccessToken() != null && com.facebook.Profile.getCurrentProfile() != null){
//Logged in so show the login button
fbLogin.setVisibility(View.VISIBLE);
fbLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//log out
LoginManager.getInstance().logOut();
gotoLogin();
}
});
}
You can logout by using LoginManager but you have to use graph request also. I am talking about log out completely so, that next time you can login with different account.
new GraphRequest(AccessToken.getCurrentAccessToken(), "/me/permissions/", null, HttpMethod.DELETE, new GraphRequest
.Callback() {
#Override
public void onCompleted(GraphResponse graphResponse) {
SharedPreferences pref = DashBoard.this.getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.clear();
editor.commit();
LoginManager.getInstance().logOut();
Intent logoutint = new Intent(DashBoard.this,MainActivity.class);
logoutint.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(logoutint);
}
}).executeAsync();
By the help of shared preferences here you can logout completely, and next time you can login with different account.
Frank version kotlin:
fun disconnectFromFacebook() {
if (AccessToken.getCurrentAccessToken() == null) {
return // already logged out
}
GraphRequest(
AccessToken.getCurrentAccessToken(),
"/me/permissions/",
null,
HttpMethod.DELETE,
GraphRequest.Callback {
LoginManager.getInstance().logOut()
}).executeAsync()
}
I am using Facebook and Parse SDK in my Android app. I followed this tutorial for Facebook login and authentication, changing between fragments for login fragment and main menu fragment depending on whether the session state is OPENED in the Session.StatusCallback. And the app works perfectly before integrating with Parse.
And now I encounter a problem. In the onResume() method of the main menu fragment, I added the following code.
final Session session = Session.getActiveSession();
if(session != null && session.isOpened()) {
Request meRequest = Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser graphUser, Response response) {
if(session == Session.getActiveSession()) {
// Check if the session is same as usual
ParseFacebookUtils.logIn(graphUser.getId(), session.getAccessToken(),
session.getExpirationDate(), new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
if (user == null) {
// The user wasn't saved.
System.out.println("User was not saved to Parse. ");
} else {
// The user has been saved to Parse.
System.out.println("User has successfully been saved to Parse.");
if (user.isNew()) {
// This user was created during this session with Facebook Login.
System.out.println("ParseUser created.");
} else {
// This user existed before.
System.out.println("User exists in Parse. Pull their values: " + user);
}
}
}
});
}
}
});
meRequest.executeAsync();
}
So when the fragment is resumed and the Facebook session is opened, the Facebook user is added to the Parse database so that I can use ParseUser to put and get data afterwards. But the problem happens when using ParseFacebookUtils.logIn(), that it makes the Facebook session CLOSED and invokes the Session.StatusCallback, thus switching the visible fragment back to the login fragment.
I was dealing with this problem all day but cannot find a solution. I have added the code below in an Application but still not work.
Parse.enableLocalDatastore(this);
Parse.initialize(this, Application_id, Client_key);
ParseFacebookUtils.initialize(getString(R.string.facebook_app_id));
Is there a way to fix this? I have read this but no quite good solution is provided. Thanks in advance!
I was trying to do the same thing today. I was using the facebook sdk's UiLifecycleHelper to do the facebook login, make the graph api request and add the user to Parse db. That is how it is done in the example you mentioned - which I think is a bit outdated.
ParseFacebookUtils handles the session and all we need to do is call the login method on it, make the graph api call, get user data like email and update the user field.
Here's some code:
private void parseFacebookLogin(){
ParseFacebookUtils.logIn(this, PARSE_FB_LOGIN_CODE, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
if (user == null) {
Log.d(tag, "Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew()) {
Log.d(tag, "User signed up and logged in through Facebook!");
Request.newMeRequest(ParseFacebookUtils.getSession(), graphUserCallback).executeAsync();
} else {
Log.d(tag, "User logged in through Facebook!");
}
}
});
}
GraphUserCallback graphUserCallback = new GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null){
getUserDataFacebook(user);
Log.d(tag, response.toString());
}
}
};
private void getUserDataFacebook(GraphUser user){
//get user data here
}
Check out Parse's docs on Facebook login.
Let me know if this works for you.
I want to get all the posts of my facebook account wall in android. I have got session but when I execute the below query then it gives an error.
new Request(fbSession,"/me?fields=posts",null, HttpMethod.GET, new Request.Callback()
{
public void onCompleted(Response response) {
ShowToast(response.toString());
}
}).executeAsync();
Error:
Active Access Token must be used to query information about the current user
Although I have an active session variable, which can retrieve my basic information
1) It means you don't have an access token or access token does not match the current logged in user.
2) You have an expired or non-working access token (perhaps left over from the last time you used the app?). You could try clearing that out and re-authenticating.
3)
if (state.isOpened())
{
new Request(fbSession,"/me?fields=posts",null, HttpMethod.GET, new Request.Callback()
{
public void onCompleted(Response response) {
ShowToast(response.toString());
}
}
).executeAsync();
}
for more info see below link:-
http://www.androidhive.info/2012/03/android-facebook-connect-tutorial/
https://developers.facebook.com/docs/android/getting-started/
Hi I am new to android programming. I want to share a image with some description on facebook.
I have tried every method explain in answers on stackoverflow. My problem is facebook dialog opens but it doesn't have specified bundle parameters.
Please help me with this. I have already tried almost 20 different code snippets. Please give me fully functional code.
#Override
public void onClick(View v) {
fb = new Facebook(app_id);
Bundle par = new Bundle();
par.putString("name", "Ass");
fb.dialog(con,"feed",par, new DialogListener(){
#Override
public void onCancel() {
// TODO Auto-generated method stub
}
#Override
public void onComplete(Bundle arg0) {
// TODO Auto-generated method stub
}
#Override
public void onError(DialogError arg0) {
// TODO Auto-generated method stub
}
#Override
public void onFacebookError(FacebookError arg0) {
// TODO Auto-generated method stub
}});
}
});
}
Have you already set up the facebook side of the application on the development page?
You need to have your app registered on facebook if you are intending to use their api and/or do graph requests or wall posts on behalf of a user authtoken.
You should read this tutorial (check part 5 for fb app registering) and all of the related info around it to really get going with facebook interaction within your app.
I know I did and end up creating my own library for log-in short-cuts or graph requests etc... it's not that simple, it will take you some time aswell.
Also;
Are you using the loginButton from the sdk? Like this:
<com.facebook.widget.LoginButton
android:id="#+id/authButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
/>
It automatically handles user login to facebook whether he has the facebook app installed or not and retrieves a session status result (onStatusChange callback).
Make sure you handle that right first and that the session is correctly initiated.
Still, posting your log will give us a better idea of what you encountering with.
I have to say, tho, that the facebook api for android is pretty solid so far so you must be doing something wrong for sure.
<<<<<< EDIT: >>>>>>
Ok then, assuming you have the user correctly logged-in (session.getActiveSession() == Session.OPENED I believe), the next step is to make sure you enabled necessary permissions.
This example is from the official facebook documentation, try it (execute publishStory() in your app):
private void publishStory() {
Session session = Session.getActiveSession();
if (session != null){
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
Bundle postParams = new Bundle();
postParams.putString("name", "Facebook SDK for Android");
postParams.putString("caption", "Build great social apps and get more installs.");
postParams.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
postParams.putString("link", "https://developers.facebook.com/android");
postParams.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
Request.Callback callback= new Request.Callback() {
public void onCompleted(Response response) {
JSONObject graphResponse = response
.getGraphObject()
.getInnerJSONObject();
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.i(TAG,
"JSON error "+ e.getMessage());
}
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(getActivity()
.getApplicationContext(),
error.getErrorMessage(),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity()
.getApplicationContext(),
postId,
Toast.LENGTH_LONG).show();
}
}
};
Request request = new Request(session, "me/feed", postParams,
HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
private boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
The code issues a POST to the users feed wall with the graph params specified at the bundle.
If session does not have the needed publish permissions, then a permission request will be issued instead. If user granted those permissions, then the RequestAsyncTask should be executed next time you call the method.
As you can see the basic idea is to get the user to log-in with his facebook account (first step), then request necessary permissions for the action, in this case, publish permissions for a wall post (second step), and lastly issue a graph request into "me/feed" with the params needed for the wall post.
In any case, if you still encountering problems please try to debug from your log as it indicates wether the request failed because of invalid session or no permissions etc...
Post your log here in that case , but this should work.
The title says it all. I'm using a custom button to fetch the user's facebook information (for "sign up" purposes). Yet, I don't want the app to remember the last registered user, neither the currently logged in person via the Facebook native app. I want the Facebook login activity to pop up each time. That is why I want to log out any previous users programmatically.
How can I do that? This is how I do the login:
private void signInWithFacebook() {
SessionTracker sessionTracker = new SessionTracker(getBaseContext(), new StatusCallback()
{
#Override
public void call(Session session, SessionState state, Exception exception) {
}
}, null, false);
String applicationId = Utility.getMetadataApplicationId(getBaseContext());
mCurrentSession = sessionTracker.getSession();
if (mCurrentSession == null || mCurrentSession.getState().isClosed()) {
sessionTracker.setSession(null);
Session session = new Session.Builder(getBaseContext()).setApplicationId(applicationId).build();
Session.setActiveSession(session);
mCurrentSession = session;
}
if (!mCurrentSession.isOpened()) {
Session.OpenRequest openRequest = null;
openRequest = new Session.OpenRequest(RegisterActivity.this);
if (openRequest != null) {
openRequest.setPermissions(null);
openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
mCurrentSession.openForRead(openRequest);
}
}else {
Request.executeMeRequestAsync(mCurrentSession, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
fillProfileWithFacebook( user );
}
});
}
}
Ideally, I would make a call at the beginning of this method to log out any previous users.
Update for latest SDK:
Now #zeuter's answer is correct for Facebook SDK v4.7+:
LoginManager.getInstance().logOut();
Original answer:
Please do not use SessionTracker. It is an internal (package private) class, and is not meant to be consumed as part of the public API. As such, its API may change at any time without any backwards compatibility guarantees. You should be able to get rid of all instances of SessionTracker in your code, and just use the active session instead.
To answer your question, if you don't want to keep any session data, simply call closeAndClearTokenInformation when your app closes.
This method will help you to logout from facebook programmatically in android
/**
* Logout From Facebook
*/
public static void callFacebookLogout(Context context) {
Session session = Session.getActiveSession();
if (session != null) {
if (!session.isClosed()) {
session.closeAndClearTokenInformation();
//clear your preferences if saved
}
} else {
session = new Session(context);
Session.setActiveSession(session);
session.closeAndClearTokenInformation();
//clear your preferences if saved
}
}
Since Facebook's Android SDK v4.0 (see changelog) you need to execute the following:
LoginManager.getInstance().logOut();
Here is snippet that allowed me to log out programmatically from facebook. Let me know if you see anything that I might need to improve.
private void logout(){
// clear any user information
mApp.clearUserPrefs();
// find the active session which can only be facebook in my app
Session session = Session.getActiveSession();
// run the closeAndClearTokenInformation which does the following
// DOCS : Closes the local in-memory Session object and clears any persistent
// cache related to the Session.
session.closeAndClearTokenInformation();
// return the user to the login screen
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
// make sure the user can not access the page after he/she is logged out
// clear the activity stack
finish();
}
Since Facebook's Android SDK v4.0 you need to execute the following:
LoginManager.getInstance().logOut();
This is not sufficient. This will simply clear cached access token and profile so that AccessToken.getCurrentAccessToken() and Profile.getCurrentProfile() will now become null.
To completely logout you need to revoke permissions and then call LoginManager.getInstance().logOut();. To revoke permission execute following graph API -
GraphRequest delPermRequest = new GraphRequest(AccessToken.getCurrentAccessToken(), "/{user-id}/permissions/", null, HttpMethod.DELETE, new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse graphResponse) {
if(graphResponse!=null){
FacebookRequestError error =graphResponse.getError();
if(error!=null){
Log.e(TAG, error.toString());
}else {
finish();
}
}
}
});
Log.d(TAG,"Executing revoke permissions with graph path" + delPermRequest.getGraphPath());
delPermRequest.executeAsync();
Session class has been removed on SDK 4.0. The login magement is done through the class LoginManager. So:
mLoginManager = LoginManager.getInstance();
mLoginManager.logOut();
As the reference Upgrading to SDK 4.0 says:
Session Removed - AccessToken, LoginManager and CallbackManager classes supercede and replace functionality in the Session class.
Yup, As #luizfelippe mentioned Session class has been removed since SDK 4.0. We need to use LoginManager.
I just looked into LoginButton class for logout. They are making this kind of check. They logs out only if accessToken is not null. So, I think its better to have this in our code too..
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if(accessToken != null){
LoginManager.getInstance().logOut();
}
private Session.StatusCallback statusCallback = new SessionStatusCallback();
logout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Session.openActiveSession(this, true, statusCallback);
}
});
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state,
Exception exception) {
session.closeAndClearTokenInformation();
}
}
Facebook provides two ways to login and logout from an account. One is to use LoginButton and the other is to use LoginManager. LoginButton is just a button which on clicked, the logging in is accomplished. On the other side LoginManager does this on its own. In your case you have use LoginManager to logout automatically.
LoginManager.getInstance().logout() does this work for you.