我正在尝试使用Graph API v2.0获取我的朋友姓名和ID,但数据返回空白:
{
"data": [
]
}
当我使用v1.0时,一切正常,并提出以下请求:
FBRequest* friendsRequest = [FBRequest requestForMyFriends];
[friendsRequest startWithCompletionHandler: ^(FBRequestConnection *connection,
NSDictionary* result,
NSError *error) {
NSArray* friends = [result objectForKey:@"data"];
NSLog(@"Found: %i friends", friends.count);
for (NSDictionary<FBGraphUser>* friend in friends) {
NSLog(@"I have a friend named %@ with id %@", friend.name, friend.id);
}
}];
但现在我无法得到朋友!
答案 0 :(得分:622)
在图谱API的v2.0中,调用/me/friends
会返回同时使用该应用的人的朋友。
此外,在v2.0中,您必须向每个用户请求user_friends
权限。每次登录时都不再包含user_friends
。每个用户都必须授予user_friends
权限才能显示在对/me/friends
的回复中。有关详细信息,请参阅the Facebook upgrade guide,或查看以下摘要。
如果您想访问非应用朋友的列表,有两种选择:
If you want to let your people tag their friends 在使用您的应用发布到Facebook的故事中,您可以使用/me/taggable_friends
API。 Use of this endpoint requires review by Facebook并且只应用于呈现朋友列表的情况,以便让用户在帖子中标记这些朋友。
If your App is a Game AND your Game supports Facebook Canvas ,您可以使用/me/invitable_friends
端点来呈现a custom invite dialog,然后将此API返回的令牌传递给{{ 3}}
在其他情况下,应用无法再检索用户朋友的完整列表(仅限那些使用user_friends
权限专门授权您的应用的朋友)。 the standard Requests Dialog.
对于希望允许其他人邀请朋友使用应用的应用,您仍然可以使用This has been confirmed by Facebook as 'by design'.或新的Send Dialog on Web和Message Dialog on iOS。
更新:Facebook已在此发布了有关这些更改的常见问题解答:Android,其中介绍了开发人员可以选择的所有选项,以便邀请朋友等。
答案 1 :(得分:17)
虽然 Simon Cross的答案被接受并且是正确的,但我想我会用一个需要做的事情的例子(android)来加强它。我会尽可能保持一般,并专注于这个问题。就个人而言,我最终将数据存储在数据库中,因此加载非常顺利,但这需要一个CursorAdapter和ContentProvider,这有点超出范围。
我自己来到这里然后想,现在是什么?!
问题
就像 user3594351 一样,我注意到朋友数据是空白的。我通过使用FriendPickerFragment找到了这个。三个月前有效的,不再有效。甚至Facebook的例子都破了。所以我的问题是“如何手动创建FriendPickerFragment?”
什么行不通
来自 Simon Cross 的选项#1不足以邀请朋友加入该应用。 Simon Cross 还推荐了“请求”对话框,但这样一次只允许5个请求。在任何给定的Facebook登录会话期间,请求对话框也显示了相同的朋友。没有用。工作原理(摘要)
选项#2有一些艰苦的工作。你必须确保你符合Facebook的新规则:1。)你是一个游戏2.)你有一个Canvas应用程序(Web Presence)3。)你的应用程序是在Facebook注册的。全部在Facebook开发者网站上完成设置。
要在我的应用程序中手动模拟朋友选择器,我执行了以下操作:
<强>详情
AsynchTask
private class DownloadFacebookFriendsTask extends AsyncTask<FacebookFriend.Type, Boolean, Boolean> {
private final String TAG = DownloadFacebookFriendsTask.class.getSimpleName();
GraphObject graphObject;
ArrayList<FacebookFriend> myList = new ArrayList<FacebookFriend>();
@Override
protected Boolean doInBackground(FacebookFriend.Type... pickType) {
//
//Determine Type
//
String facebookRequest;
if (pickType[0] == FacebookFriend.Type.AVAILABLE) {
facebookRequest = "/me/friends";
} else {
facebookRequest = "/me/invitable_friends";
}
//
//Launch Facebook request and WAIT.
//
new Request(
Session.getActiveSession(),
facebookRequest,
null,
HttpMethod.GET,
new Request.Callback() {
public void onCompleted(Response response) {
FacebookRequestError error = response.getError();
if (error != null && response != null) {
Log.e(TAG, error.toString());
} else {
graphObject = response.getGraphObject();
}
}
}
).executeAndWait();
//
//Process Facebook response
//
//
if (graphObject == null) {
return false;
}
int numberOfRecords = 0;
JSONArray dataArray = (JSONArray) graphObject.getProperty("data");
if (dataArray.length() > 0) {
// Ensure the user has at least one friend ...
for (int i = 0; i < dataArray.length(); i++) {
JSONObject jsonObject = dataArray.optJSONObject(i);
FacebookFriend facebookFriend = new FacebookFriend(jsonObject, pickType[0]);
if (facebookFriend.isValid()) {
numberOfRecords++;
myList.add(facebookFriend);
}
}
}
//make sure there are records to process
if (numberOfRecords > 0){
return true;
} else {
return false;
}
}
@Override
protected void onProgressUpdate(Boolean... booleans) {
//no need to update this, wait until the whole thread finishes.
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
/*
User the array "myList" to create the adapter which will control showing items in the list.
*/
} else {
Log.i(TAG, "Facebook Thread unable to Get/Parse friend data. Type = " + pickType);
}
}
}
我创建的FacebookFriend课程
public class FacebookFriend {
String facebookId;
String name;
String pictureUrl;
boolean invitable;
boolean available;
boolean isValid;
public enum Type {AVAILABLE, INVITABLE};
public FacebookFriend(JSONObject jsonObject, Type type) {
//
//Parse the Facebook Data from the JSON object.
//
try {
if (type == Type.INVITABLE) {
//parse /me/invitable_friend
this.facebookId = jsonObject.getString("id");
this.name = jsonObject.getString("name");
//Handle the picture data.
JSONObject pictureJsonObject = jsonObject.getJSONObject("picture").getJSONObject("data");
boolean isSilhouette = pictureJsonObject.getBoolean("is_silhouette");
if (!isSilhouette) {
this.pictureUrl = pictureJsonObject.getString("url");
} else {
this.pictureUrl = "";
}
this.invitable = true;
} else {
//parse /me/friends
this.facebookId = jsonObject.getString("id");
this.name = jsonObject.getString("name");
this.available = true;
this.pictureUrl = "";
}
isValid = true;
} catch (JSONException e) {
Log.w("#", "Warnings - unable to process FB JSON: " + e.getLocalizedMessage());
}
}
}
答案 2 :(得分:12)
您可以提取仅授权该应用的朋友列表。
使用Graph API 1.0的应用程序将在2015年4月30日之前运行,之后将弃用。
请参阅以下链接以获取有关此
的更多详细信息https://developers.facebook.com/docs/graph-api/reference/v2.2/user/friends
https://developers.facebook.com/docs/apps/faq#invite_to_app
希望这有帮助
答案 3 :(得分:2)
正如Simon提到的,这在新的facebook API中是不可能的。 从技术上讲,可以通过浏览器自动化实现。
使用WatiN的示例实施
class FacebookUser
{
public string Name { get; set; }
public long Id { get; set; }
}
public IList<FacebookUser> GetFacebookFriends(string email, string password, int? maxTimeoutInMilliseconds)
{
var users = new List<FacebookUser>();
Settings.Instance.MakeNewIeInstanceVisible = false;
using (var browser = new IE("https://www.facebook.com"))
{
try
{
browser.TextField(Find.ByName("email")).Value = email;
browser.TextField(Find.ByName("pass")).Value = password;
browser.Form(Find.ById("login_form")).Submit();
browser.WaitForComplete();
}
catch (ElementNotFoundException)
{
// we're already logged in
}
browser.GoTo("https://www.facebook.com/friends");
var watch = new Stopwatch();
watch.Start();
Link previousLastLink = null;
while (maxTimeoutInMilliseconds.HasValue && watch.Elapsed.TotalMilliseconds < maxTimeoutInMilliseconds.Value)
{
var lastLink = browser.Links.Where(l => l.GetAttributeValue("data-hovercard") != null
&& l.GetAttributeValue("data-hovercard").Contains("user.php")
&& l.Text != null
).LastOrDefault();
if (lastLink == null || previousLastLink == lastLink)
{
break;
}
var ieElement = lastLink.NativeElement as IEElement;
if (ieElement != null)
{
var htmlElement = ieElement.AsHtmlElement;
htmlElement.scrollIntoView();
browser.WaitForComplete();
}
previousLastLink = lastLink;
}
var links = browser.Links.Where(l => l.GetAttributeValue("data-hovercard") != null
&& l.GetAttributeValue("data-hovercard").Contains("user.php")
&& l.Text != null
).ToList();
var idRegex = new Regex("id=(?<id>([0-9]+))");
foreach (var link in links)
{
string hovercard = link.GetAttributeValue("data-hovercard");
var match = idRegex.Match(hovercard);
long id = 0;
if (match.Success)
{
id = long.Parse(match.Groups["id"].Value);
}
users.Add(new FacebookUser
{
Name = link.Text,
Id = id
});
}
}
return users;
}
实现此方法的原型(使用C#/ Watin)请参阅https://github.com/svejdo1/ShadowApi 它还允许动态更新正在检索联系人列表的facebook连接器。
答案 4 :(得分:2)
使用您的javascript代码尝试/ me / taggable_friends?limit = 5000
OR
尝试图API
https://graph.facebook.com/v2.3/user_id_here/taggable_friends?access_token=
玩得开心
答案 5 :(得分:2)
在Swift 4.2和Xcode 10.1中
如果要从FB获取朋友列表,则需要提交应用以在FB中进行审核。请参阅一些登录权限。
https://developers.facebook.com/docs/apps/review/login-permissions
这里有两个步骤
1)首先,您的应用状态必须为“实时”
2)从FB获取必需的权限。
https://developers.facebook.com/apps/
完成步骤。
例如:user_friends,user_videos,user_posts等。
例如:user_events
就像所有请求(user_friends,user_events,user_videos,user_posts等)的提交一样。
最后将您的应用提交审核。
如果您的评论接受了FB表,那么您现在就有资格阅读联系人等信息。
答案 6 :(得分:-1)
在FBSDKGraphAPI v2.0或更高版本中,您必须在FB登录时请求每个用户的user_friends权限。因为默认情况下每次登录都不再包含user_friends,我们必须添加。每个用户必须授予user_friends权限才能显示在对/ me / friends
的响应中 let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.loginBehavior = FBSDKLoginBehavior.web
fbLoginManager.logIn(withReadPermissions: ["email","user_friends","public_profile"], from: self) { (result, error) in
if (error == nil){
let fbloginresult : FBSDKLoginManagerLoginResult = result!
if fbloginresult.grantedPermissions != nil {
if(fbloginresult.grantedPermissions.contains("email")) {
// Do the stuff
}else {
}
}else {
}
}
}
的屏幕
如果用户按下继续按钮,则会设置权限。当您使用FBGraphAPI访问好友列表时,将列出您登录上述应用程序的朋友
if((FBSDKAccessToken.current()) != nil){
FBSDKGraphRequest(graphPath: "/me/friends", parameters: ["fields" : "id,name"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil){
print(result!)
}
})
}
输出将包含在通过Facebook登录您的应用程序时授予user_friends权限的用户
{
data = (
{
id = xxxxxxxxxx;
name = "xxxxxxxx";
}
);
paging = {
cursors = {
after = xxxxxx;
before = xxxxxxx;
};
};
summary = {
"total_count" = 8;
};
}