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

Kas*_*ico 366 facebook facebook-graph-api facebook-ios-sdk facebook-graph-api-v2.0

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

{
  "data": [
  ]
}
Run Code Online (Sandbox Code Playgroud)

当我使用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);
    }
}];
Run Code Online (Sandbox Code Playgroud)

但现在我不能得到朋友!

Sim*_*oss 626

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

此外,在v2.0中,您必须请求user_friends每个用户的许可.user_friends默认情况下不再包含在每次登录中.每个用户都必须授予user_friends权限才能出现在响应中/me/friends.有关更多详细信息,请参阅Facebook升级指南,或查看下面的摘要.

如果您想访问非应用程序使用的朋友列表,有两种选择:

  1. 如果您想让您的人员使用您的应用程序在他们发布到Facebook的故事中标记他们的朋友,您可以使用该/me/taggable_friendsAPI.使用此端点需要通过Facebook进行审核,并且仅应用于您呈现朋友列表以便让用户在帖子中标记它们的情况.

  2. 如果您的应用程序是游戏并且您的游戏支持Facebook Canvas,则可以使用/me/invitable_friends端点来呈现自定义邀请对话框,然后将此API返回的标记传递到标准请求对话框.

在其他情况下,应用程序无法再检索用户朋友的完整列表(仅限那些使用user_friends权限明确授权您的应用的朋友).这已被Facebook确认为"按设计".

对于希望允许人们邀请朋友使用应用程序的应用程序,您仍然可以使用Web上发送对话框iOSAndroid 上的新消息对话框.

更新:Facebook已在此发布了有关这些更改的常见问题解答:https://developers.facebook.com/docs/apps/faq,其中介绍了开发人员可以选择的所有选项,以便邀请朋友等.

  • 我无法理解为什么他们不得不限制它.我的意思是旧系统过于滥用,但这个系统几乎没用.查看所有朋友的公开个人资料肯定不是隐私问题.除非你认为友谊的联系本身就是私人的(但是为什么不是在可标记的朋友的情况下).这不是限制隐私滥用的举动,这是一个副作用,他们希望关闭普通(非Facebook附属)开发人员使用Facebook数据发展业务的能力. (7认同)
  • Facebook最近发布了可用数据的重大更改:请参阅[changelog](https://developers.facebook.com/docs/graph-api/changelog/breaking-changes/#4-4-2018)。`taggable_friends`现在不返回任何内容。另外,必须先进行登录审核,然后才能授予“ user_friends”权限。 (2认同)

LEO*_*LEO 17

虽然西蒙克罗斯的回答是被接受和正确的,但我想我会用一个例子(android)来加强它需要做些什么.我将尽可能保持一般,并专注于问题.我个人最终将数据存储在数据库中,因此加载非常顺利,但这需要一个CursorAdapter和ContentProvider,这里有点超出范围.

我自己来到这里然后想,现在是什么?!

问题

就像user3594351一样,我注意到朋友数据是空白的.我通过使用FriendPickerFragment找到了这个.三个月前有效的,不再有效.甚至Facebook的例子都破了.所以我的问题是'如何手动创建FriendPickerFragment?

什么没有奏效

Simon Cross的选项#1 不足以邀请朋友加入应用程序.Simon Cross还推荐了Requests Dialog,但这样一次只允许5个请求.在任何给定的Facebook登录会话期间,请求对话框也显示了相同的朋友.没有用.

工作原理(摘要)

选项#2有一些艰苦的工作.你必须确保你完成Facebook的新规则:1.)你是一个游戏2.)你有一个Canvas应用程序(Web Presence)3.)你的应用程序是在Facebook注册的.全部在Facebook开发者网站上完成设置.

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

  1. 创建一个显示两个片段的选项卡活动.每个片段都显示一个列表.一个片段为可用的朋友(/我/朋友)和另一个片段为可邀请的朋友(/ me/invitable_friends).使用相同的片段代码来呈现两个选项卡.
  2. 创建一个AsyncTask,它将从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);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我创建的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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 非游戏应用程序怎么样?一个约会网站......一个找人的游戏,一个找餐馆的应用程序......找到餐馆等的游戏,你就明白了.那么这真的很接近游戏,或者这只是一种强迫你在Facebook内放置应用并在他们的广告平台上花钱的方式吗?谁将决定游戏是什么?谁决定你的应用程序实际上是游戏?不要误解我,但对我来说,阻止非游戏应用是没有意义的,除非你只是想强迫他们使用facebook生态系统. (20认同)

Job*_*ohn 12

Facebook现在已经修改了他们的政策.如果您的应用程序没有Canvas实现并且您的应用程序不是游戏,则无论如何您都无法获得整个好友列表.当然还有taggable_friends,但那只是用于标记.

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

使用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

希望这可以帮助