I am developing an application in which I am using Facebook SDK for different purposes. Currently I have implemented Login through Facebook. Now my next task is to fetch all the photos of the logged in user and display all of them in a grid. I am following the official facebook developer website as a reference for this task. Following is the code that I am using to fetch the user photos.
new Request(
Session.getActiveSession(),
"/me/photos",
getRequestParameters(),
HttpMethod.GET,
new Request.Callback() {
public void onCompleted(Response response) {
/* handle the result */
Log.d("Response ","Response " + response);
mpBar.setVisibility(View.GONE);
}
}
).executeAsync();
private Bundle getRequestParameters()
{
String accessToken = LoginSigbUpCustomerNew.mytoken;
Bundle parameters = new Bundle(1);
parameters.putString("access_token", accessToken);
return parameters;
}
Here, I am getting response like this :-
{Response: responseCode: 200, graphObject: GraphObject{graphObjectClass=GraphObject, state={"data":[]}}, error: null, isFromCache:false}
I cant understand why the data array is empty. Also I am requesting the user_photos permission from user. So where the thing is wrong.
I am new to this Facebook SDK and dont know how to solve this. If anyone can help me it would be great.
Thanks in advance.
Your code to request your photos is just fine according to the documentation of Facebook SDK however I think that you forgot to request permission from the user who's logged in (you in this case).
Copied from Facebook SDK documentation: A user access token with user_photos permission is required to see all photos that person is tagged in or has uploaded.
The following link gives you a small tutorial on how to add access tokens to the login button: https://developers.facebook.com/docs/android/login-with-facebook/v2.2?locale=en_GB#step3
In your case it would be (code snippet is for activities only, for fragments: click the url above and follow the tutorial there. Pretty straight forward):
...
LoginButton authButton = (LoginButton) findViewById(R.id.ID_OF_YOUR_LOGIN_BUTTON);
authButton.setReadPermissions(Arrays.asList("user_photos"));
...
In your overriding onCreate method.
Method two:
...
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this)
.setPermissions(Arrays.asList("user_photos"))
.setCallback(YOUR_CALLBACK_CLASS_VARIABLE));
} else {
// Open an active session. Basically happens when someone is already logged in.
}
...
Before making the call to request all the user photos, you can simply open a new request when the user hasn't logged in yet. This can happen in View.OnClickListener class of a Button as it seems that you're not LoginButton of Facebook.
YOUR_CALLBACK_CLASS_VARIABLE is your class implementing Session.StatusCallback. I'm quite certain you know what it is and what it does.
Method three:
...
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, Arrays.asList("user_photos"));
session.requestNewReadPermissions(newPermissionsRequest);
...
When the user is already logged in (so after the user is logged in) and you wish to request additional permissions from the user to access his photos or whatsoever. This is by the way all written in the docs of Facebook SDK for Android.
For more information: https://developers.facebook.com/docs/android/login-with-facebook/v2.2?locale=en_GB#step3
If the request returns an empty result, check whether the used Access Token contains the user_photos permission:
https://developers.facebook.com/docs/graph-api/reference/v2.2/user/photos#readperms
You can inspect the Acces Token via
https://developers.facebook.com/docs/facebook-login/access-tokens#debug
Request:
GET /debug_token?
input_token={input-token}&
access_token={access-token}
Related
I have tried using the code below and if add old facebook sdk it workd fine but new sdk I get only the friend who is on app.How can I get the list of all friends in new sdk? .I really appreciate any help .Thanks in Advance.:
new Request(
MainActivity.facebook.getSession(),
"/me/friends",
null,
HttpMethod.GET,
new Request.Callback() {
#Override
public void onCompleted(Response response) {
/* handle the result */
Toast.makeText(activity, response.toString(), 5).show();
}
}
).executeAsync();
Short Answer: You CanĀ“t.
Since v2.0, you can only get the friends who authorized your App too, for privacy reasons. An App should not know about anyone who does not use the App.
If you want the names to tag them, there is taggable_friends. If you want to invite them, use invitable_friends. But check out the docs for their limitations.
I have an ASP.NET WebApi 2.1 application with OAuth2 configured. I have and Android client where I can do authentication by using the following methods:
WebView approach (Web Api External Providers): redirect to https://www.facebook.com/dialog/oauth..., user do login there, FB asks for permissions, redirects to my url, catch it, access token got, done.
Facebook SDK approach: under the hood it does: redirect to https://graph.facebook.com/oauth..., user do login there, FB asks for permissions, redirects to my url, catch it, access token got, done.
The problem is, if I go with the WebView version, the token is good for authorizing user in my Web Api application, but I cannot call Graph API by using it, I receive OAuthException 190 (no subcode).
But if I do the SDK authorization, Graph API is accessible (through the Android Facebook SDK), but using the token I've got from it, Web Api authorization is not working, I get 401 by calling Authorization/UserInfo.
So my question are the above token types interchangeable somehow?
Any help would be greatly appreciated.
Sorry if that was not clear, I'm using Web Api w/ ASP.NET Identity 2.0 template, so OAuth plumbing code is already present there.
I was able to find an answer to my own question, let me share it with you.
So the problem is that the token I've got from the Facebook's OAuth dialog after the redirect is not the same token that my application can use to call Facebook Graph APIs in the name of the actual user. That Graph API token is reachable at the following point:
Assume you are using the mentioned template above, you can find App_Data/Startup.Auth.cs class with definition of a FacebookAuthenticationOptions instance. There you can catch the API token and can persist that into the database. For example:
var fbopts = new FacebookAuthenticationOptions
{
AppId = Global.Config.ExternalServices.FacebookAppID,
AppSecret = Global.Config.ExternalServices.FacebookAppSecret,
Scope = { "email", "user_friends", "publish_actions" },
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = async context =>
{
// This token will be OK for calling Graph API
string accessToken = context.AccessToken;
using (var tracer = Global.Tracer.CreateBuilder())
{
try
{
tracer.InformationLine("Storing Facebook OAuth token: " + accessToken);
string fbUserID = context.Identity.GetUserId();
string fbUserName = context.Identity.Name;
tracer.InformationLine("Facebook User ID: " + fbUserID);
tracer.InformationLine("Facebook User Name: " + fbUserName);
// Store it into the db
// assume Task StoreOAuthToken(string providerName, string providerKey, string accessToken) is defined
await StoreOAuthToken("Facebook", fbUserID, accessToken);
}
catch (Exception ex)
{
tracer.ErrorLine("Failed.", ex);
}
}
}
}
};
app.UseFacebookAuthentication(fbopts);
At this point you're gonna have a row in a table that consists of the following columns:
OAuthAccessToken.ProviderName
OAuthAccessToken.ProviderKey
OAuthAccessToken.AccessToken
Now you can provide an API to your consumers to have that API token for calling Graph API, like:
[Route("AccessTokens")]
[Authorize]
public async Task<List<OAuthAccessToken>> GetAccessTokens(string providerName = null)
{
var userID = User.Identity.GetUserId();
var q = from l in this.Context.AspNetUserLogins // Managed by ASP.NET Identity 2.0
from t in this.Context.OAuthAccessTokens // Stored by you with above code
where l.UserId == userID && t.ProviderName == l.LoginProvider && t.ProviderKey == l.ProviderKey
select t;
if (!string.IsNullOrEmpty(providerName)) q = q.Where(t => t.ProviderName == providerName);
return await q.ToListAsync();
}
So on Android after doing a Facebook login I have the Bearer token for my application's Web Api calls, and I can get my token for accessing Graph API by calling the action above.
Maybe there are easier methods for achieving the above. Please let me know if you find any.
I am trying to fetch friends' list in Facebook SDK 3.8 but it returning Empty User List.
I have also set the permissions of user_friends. Please see the following code.
<code>
LoginButton loginButton = (LoginButton) findViewById(R.id.login_button);
loginButton.setReadPermissions(Arrays.asList("user_friends"));
Request request = Request.newMyFriendsRequest(session, new Request.GraphUserListCallback() {
#Override
public void onCompleted(List<GraphUser> users, Response response) {
Log.i("activitytag", "UserListSize: " + users.size());
}
});
request.executeAsync();
</code>
I am getting the UserListSize to 0. What am I missing?
If you created your app after April 30, 2014, then you're using version 2.0 of the graph API, in which case the newMyFriendsRequest will only return friends who are also using your app. You should also update your SDK to the latest (3.14.1).
In facebook api v2.0 has no way to get all friends list.
but if you want to get all friend list ONLY IN GAME then you can call
Either
Invitable Friends List:
you may use the https://developers.facebook.com/docs/graph-api/reference/v2.0/user/invitable_friends API.
OR
Taggable Friends List:
the https://developers.facebook.com/docs/graph-api/reference/v2.0/user/taggable_friends
for more detail please read facebook change log:
Facebook Change log
How do I get facebook realtime updates with android .Basically everytime the user's friendlist changes I need to update the count.I used the code below but I get error msg :
{This method must be called with an app access_token.}, isFromCache:false}
I really appreciate any help.Thanks in Advance.
code:
Bundle params = new Bundle();
params.putString("object", "user");
params.putString("callback_url", "http://example.com/callback/update.php");
params.putString("fields", "friends");
params.putString("verify_token", "1234");
/* make the API call */
new Request(
session,
"/12345/subscriptions",
params,
HttpMethod.POST,
new Request.Callback() {
public void onCompleted(Response response) {
/* handle the result */
}
}
).executeAsync();
Note: session =fb.getsession();
This error:
"This method must be called with an app access_token."
is quite straight-forward. You just need to make this API call with an App access token, instead of a normal access token (user token). To use it with your call simply add another parameter: access_token and make the call.
The App Access token is nothing but, APP_ID|APP_SECRET, or you can make the call (ref.)-
GET /oauth/access_token?
client_id={app-id}
&client_secret={app-secret}
&grant_type=client_credentials
But beware, its not recommended to expose app access token on the client side, since its like a password of your app.
I'm trying to discover if a user likes a specific facebook page by using Graph API inside an android application using the FB SDK v3.
The following call works and reports all of the likes of the user along with every other detail to do with each resulting item.
Request.executeGraphPathRequestAsync(session, "me/likes", new Request.Callback()
Since I'm not interested in any peripheral data, I just want to get the id back so I can lookup the page I'm interested in, but when I add the parameters as follows...
Request.executeGraphPathRequestAsync(session, "me/likes?fields=id", new Request.Callback()
... no object is returned from the call. If I post the same queries in the Graph API explorer they give back the expected results.
In addition to this question, is it at all possible to limit the result of the query to just the page ID to begin with, since I already know that piece of information? I have no use for the rest of the data being returned and would prefer not to chew up user bandwidth unnecessarily. I've searched high and low and it doesn't seem possible. Even the FQL explorer doesn't work when trying to limit by both user and page iD as the example suggests. I get an empty result set when adding 'AND page_id=xxx' to the query.
As far as i know, you cant run queries with field in 'executeGraphPathRequestAsync'.
instead use 'Request' and run in with 'RequestAsyncTask'.
Short example:
String grapPath = "me/home";
Bundle params = new Bundle();
params.putString("fields", "type,id,object_id,created_time,from,picture,likes");
params.putString("limit", "500");
Request request = new Request(session, grapPath, params, HttpMethod.GET, new Callback()
{
#Override
public void onCompleted(Response response)
{
if (response != null)
{
Log.d(TAG_NAME, "response: " + response.toString());
}
}
});
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
Hope i managed to help you :)
The Facebook SDK will add the "?access_token" to the end of the graph path string. So the graph command ends up looking like:
me/likes?fields=id?access_token
Break out the fields into a params Bundle.
Found this issue resolved in a Facebook bug post:
http://developers.facebook.com/bugs/314504765319932?browse=search_5116b87d245900257505334