Facebook Graph API v2.0+/me/friends返回空,或仅返回同时使用我的应用程序的朋友

Facebook Graph API v2.0+/me/friends返回空,或仅返回同时使用我的应用程序的朋友,facebook,facebook-graph-api,facebook-ios-sdk,facebook-graph-api-v2.0,Facebook,Facebook Graph Api,Facebook Ios Sdk,Facebook Graph Api V2.0,我正在尝试使用Graph API v2.0获取我的朋友姓名和ID,但数据返回为空: { 数据:[ ] } 当我使用v1.0时,以下请求一切正常: FBRequest*friendsRequest=[FBRequestFormyFriends]; [FriendsRequestStartWithCompletionHandler:^FBRequestConnection*连接, NSDictionary*结果, N错误*错误{ NSArray*friends=[result objectForKe

我正在尝试使用Graph API v2.0获取我的朋友姓名和ID,但数据返回为空:

{ 数据:[ ] } 当我使用v1.0时,以下请求一切正常:

FBRequest*friendsRequest=[FBRequestFormyFriends]; [FriendsRequestStartWithCompletionHandler:^FBRequestConnection*连接, NSDictionary*结果, N错误*错误{ NSArray*friends=[result objectForKey:@data]; NSLog@Found:%i个朋友,朋友数; 对于NSDictionary*朋友中的朋友{ NSLog@I有一个名为%@的朋友,id为%@,friend.name,friend.id; } }];
但是现在我找不到朋友了

在Graph API的v2.0中,调用/me/friends会返回同样使用该应用程序的人的朋友

此外,在v2.0中,您必须向每个用户请求用户\u friends权限。默认情况下,用户朋友不再包括在每个登录中。每个用户必须授予用户\u friends权限才能出现在对/me/friends的响应中。有关更多详细信息,请参阅,或查看下面的摘要

如果您想访问非应用程序好友列表,有两个选项:

在他们使用你的应用程序发布到Facebook的故事中,你可以使用/me/taggable_-friends API。并且只应用于呈现朋友列表以便用户在帖子中标记他们的情况

,您可以使用/me/invitable_friends端点进行渲染,然后将此API返回的令牌传递给

在其他情况下,应用程序将不再能够检索用户朋友的完整列表,而只能检索那些使用“用户朋友”权限专门授权您的应用程序的朋友

对于希望允许人们邀请朋友使用应用的应用,您仍然可以使用或新的和


更新:Facebook在这里发布了一个关于这些变化的常见问题解答:它解释了开发者可以邀请朋友等的所有选项。

正如Simon提到的,这在新的Facebook API中是不可能的。从技术上讲,你可以通过浏览器自动化来实现

这违反了Facebook的政策,因此根据您居住的国家,这可能是不合法的 您必须使用您的凭据/向用户索要凭据并可能存储它们存储密码即使对称加密也不是一个好主意 当Facebook改变他们的API时,你也必须更新浏览器自动化代码。如果你不能强制更新你的应用程序,你应该把浏览器自动化作为Web服务发布 这绕过了OAuth概念 另一方面,我的感觉是我拥有自己的数据,包括我的朋友列表,Facebook不应该限制我通过API访问这些数据 示例实现使用:

类FacebookUser { 公共字符串名称{get;set;} 公共长Id{get;set;} } 公共IList GetFacebookFriendsstring电子邮件,字符串密码,int?MaxTimeouting毫秒 { var用户=新列表; Settings.Instance.MakeNewIeInstanceVisible=false; 使用var browser=newiehttps://www.facebook.com { 尝试 { browser.TextFieldFind.bynamemail.Value=电子邮件; browser.TextFieldFind.ByNamepass.Value=密码; browser.FormFind.ByIdlogin_form.Submit; browser.WaitForComplete; } catch ElementNotFoundException { //我们已经登录了 } 我明白了ohttps://www.facebook.com/friends; var手表=新秒表; 看,开始; Link-previousLastLink=null; 而maxtimeoutinmillizes.HasValue&&watch.appeased.totalmillizesl.GetAttributeValuedata-hovercard!=null &&l.GetAttributeValuedata-hovercard.ContainesUser.php &&l.文本!=null .LastOrDefault; 如果lastLink==null | | previousLastLink==lastLink { 打破 } var ieElement=lastLink.NativeElement作为ieElement; 如果ieElement!=null { var htmlElement=ieElement.AsHtmlElement; htmlElement.scrollIntoView; browser.WaitForComplete; } previousLastLink=lastLink; } var links=browser.links.Wherel=>l.GetAttributeValuedata-hovercard!=null &&l.GetAttributeValuedata-hovercard.ContainesUser.php &&l.文本!=null 托利斯特先生; var idRegex=new Regexid=?[0-9]+; 链接中的foreach var链接 { 字符串hovercard=link.GetAttributeValuedata-hovercard; var match=idRegex.MATCHOVERCARD; 长id=0; 如果匹配,成功 { id=long.Parsematch.Groups[id].Value; } users.Addnew FacebookUser { Name=link.Text, Id=Id }; } } 返回用户; } 原型机智 h使用C/WatiN实现此方法,请参见。它还允许动态更新正在检索联系人列表的Facebook connector。

虽然Simon Cross的回答被接受且正确,但我想我会用一个Android示例来说明需要做什么。我会尽我所能保持它的概括性,只关注这个问题。就我个人而言,我最终将东西存储在数据库中,以便顺利加载,但这需要一个CursorAdapter和ContentProvider,这在这里有点超出范围

我自己来到这里,然后想,现在怎么办

问题

就像user3594351一样,我注意到好友数据是空白的。我通过使用FriendPickerFragment发现了这一点。三个月前有效的方法现在不再有效了。就连Facebook的例子也不例外。所以我的问题是“我如何手工创建FriendPickerFragment?”

什么不起作用

Simon Cross的选项1不够强大,无法邀请朋友使用该应用程序。Simon Cross也推荐使用“请求”对话框,但一次只允许五个请求。“请求”对话框还显示了在任何特定Facebook登录会话中的相同好友。没用

什么工作总结

选项2需要一些艰苦的工作。你必须确保遵守Facebook的新规则:1。你是第二场比赛。您有一个画布应用程序Web Presence 3。你的应用已在Facebook注册。这一切都是在Facebook开发者网站的“设置”下完成的

为了在我的应用程序中手动模拟好友选取器,我执行了以下操作:

创建一个显示两个片段的选项卡活动。每个片段显示一个列表。一个片段用于可用的朋友/我/朋友,另一个片段用于不可侵犯的朋友/我/不可侵犯的朋友。使用相同的片段代码呈现两个选项卡。 创建一个异步任务,该任务将从Facebook获取好友数据。加载数据后,将其扔给适配器,适配器将向屏幕呈现值。 细节

异步任务

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);
        }
    }
}

Facebook现在已经修改了他们的政策。如果你的应用程序没有画布实现,并且你的应用程序不是游戏,那么你无论如何都无法获取整个好友列表。当然也有taggable_friends,但那只是用于标记的

您将能够提取仅授权该应用程序的好友列表

使用Graph API 1.0的应用程序将一直运行到2015年4月30日,之后将被弃用

有关详细信息,请参阅以下内容:

使用JavaScript代码尝试/me/taggable\u friends?limit=5000

请尝试以下方法:


在Facebook SDK Graph API v2.0或更高版本中,您必须在登录Facebook时向每个用户请求user_friends权限,因为默认情况下,用户_friends不再包含在每个登录中;我们必须补充一点

每个用户必须授予用户\u friends权限才能出现在对/me/friends的响应中

因此,在登录Facebook时,它会显示一个包含所有权限的屏幕:

如果用户按下“继续”按钮,将设置权限。当您使用Graph API访问好友列表时,将列出按上述方式登录应用程序的好友

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登录到您的应用程序时授予用户_friends权限的用户

{
    data = (
             {
                 id = xxxxxxxxxx;
                 name = "xxxxxxxx";
             }
           );
    paging = {
        cursors = {
            after = xxxxxx;
            before = xxxxxxx;
        };
    };
    summary = {
        "total_count" = 8;
    };
}
在4.2和10.1中:

如果你想从Facebook获得好友列表,你需要提交你的应用程序,以便在Facebook上查看。请参阅一些登录权限:

以下是两个步骤:

1首先,您的应用程序状态为必须处于Live状态

2从Facebook获取所需权限

{
    data = (
             {
                 id = xxxxxxxxxx;
                 name = "xxxxxxxx";
             }
           );
    paging = {
        cursors = {
            after = xxxxxx;
            before = xxxxxxx;
        };
    };
    summary = {
        "total_count" = 8;
    };
}
1启用我们的应用程序状态live: 转到应用程序页面并选择您的应用程序

在仪表板右上角选择状态

提交隐私策略URL

选择类别

现在我们的应用程序处于实时状态

完成了一个步骤

2提交我们的应用程序以供审查: 首先发送所需的请求

例如:用户朋友、用户视频、用户帖子等

其次,转到当前请求页面

示例:用户事件

提交所有详细信息

像这样提交所有请求用户朋友、用户事件、用户视频、用户帖子等

最后提交你的应用程序进行审查

如果你的评论被Facebook接受,你现在就有资格阅读联系人等等


您的代码假定应用程序可以访问用户的用户名和密码。OAuth不是这样工作的,大多数用户不会向应用程序提供他们的FB用户名和密码。这将是一个巨大的安全风险。这违反了Facebook的政策。不应遵循此建议。另一方面,在黑客中保护用户的凭据甚至不安全。万一有人决定使用你的代码,请通过将uri更改为https来确保它使用SSL。另外还有一个是为了把它推到他们的脸上!你们听起来都像Facebook的政策是某种国际法和法律
打破它,你就是罪犯。此外,你认为Facebook只为用户着想,我认为这是错误的,就像@OndrejSvejdar所说的,因为如果你想在其他应用中被看到,他们只会让你选择。我认为这只是Facebook的一个举动,目的是通过他们的平台免费破坏其他人的成长。相反,人们应该开始直接在Facebook上开发应用程序、服务、游戏、新闻等。如果他们不愿意的话,可以为Facebook广告付费。解决这个问题的一个可能方法是非游戏应用程序如何?一个约会网站。。。一个寻找人的游戏,一个寻找餐馆的应用。。。一个寻找餐馆等的游戏。你明白了。那么,这真的很接近游戏,还是这只是一种强迫你在Facebook上放置应用程序并在他们的广告平台上花钱的方式?谁来决定什么是游戏?谁决定你的应用程序实际上是一个游戏?不要误解我的意思,但对我来说,阻止非游戏应用毫无意义,除非你只是想强迫它们使用facebook生态系统。@Mário这就是facebook的意图。你可以把任何东西都标记为游戏,因为他们不在乎它是否真的是游戏。他们关心的只是从你的口袋里拿钱。自从你上次编辑或我们在同一页以来有什么新闻吗?在提交评论的项目中看不到taggable_朋友。我不明白他们为什么要限制这么多。我的意思是旧的系统太容易被滥用了,但这一个几乎是无用的。看到你所有朋友的公开资料肯定不是隐私问题。除非你认为友谊的联系本身是私人的,但为什么不是在可标记的朋友的情况下呢。这不是限制隐私滥用的举措,这是一种副作用,他们希望关闭普通非facebook关联开发者使用facebook数据发展业务的能力。facebook最近发布了对可用数据的重大更改:见。Tagu朋友现在不返回任何内容。而且在授予用户\朋友权限之前,需要进行登录审核。如果API不允许您执行基本任务(如列出朋友),那么提供API有什么意义?我认为,这里的向下投票是因为使用此端点需要Facebook审核,并且只应用于在Facebook中呈现朋友列表的情况以便让用户在帖子中标记它们。您可以在所选答案中了解更多信息。{data:[],summary:{total_count:414}}我得到了这个json数据块null not get friends。我能做什么?用户和朋友的权限非常有限。根据Facebook 2019年4月的文档:[仅此]授予应用程序访问同样使用该应用程序的朋友列表的权限。此权限仅限于有限的合作伙伴,使用需要事先获得Facebook的批准。为了让一个人出现在另一个人的好友列表中,两个人必须已与应用共享了他们的好友列表,并且在登录期间未禁用此权限。
{
    data = (
             {
                 id = xxxxxxxxxx;
                 name = "xxxxxxxx";
             }
           );
    paging = {
        cursors = {
            after = xxxxxx;
            before = xxxxxxx;
        };
    };
    summary = {
        "total_count" = 8;
    };
}