it-swarm-ko.com

Facebook/API v2.0 + -/me/friends가 사용하는 데 성공했습니다.

그래프 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);
    }
}];

하지만 지금 나는 친구를 사귈 수 없다!

363
KasliCo

그래프 API v2.0에서 /me/friends을 (를) 호출하면 앱을 사용하는 사람의 친구가 반환됩니다.

또한 v2.0에서는 각 사용자에게 user_friends 권한을 요청해야합니다. user_friends는 더 이상 기본적으로 모든 로그인에 포함되지 않습니다. user_friends에 대한 응답으로 나타나려면 각 사용자에게 /me/friends 권한을 부여해야합니다. 자세한 내용은 Facebook 업그레이드 안내서 를 참조하거나 아래 요약을 검토하십시오.

앱을 사용하지 않는 친구 목록에 액세스하려면 두 가지 옵션이 있습니다.

  1. 사람들이 앱을 사용하여 Facebook에 게시 한 스토리에서 친구에 태그를 지정하게하려면 /me/taggable_friends API를 사용할 수 있습니다. 이 엔드 포인트를 사용하려면 Facebook 의 검토가 필요하며 사용자가 게시물에 친구를 태그 할 수 있도록 친구 목록을 렌더링하는 경우에만 사용해야합니다.

  2. 앱이 게임이고 게임에서 Facebook Canvas를 지원하는 경우 /me/invitable_friends 엔드 포인트 를 사용자 정의 초대 대화 상자 로 렌더링 한 다음이 API에서 리턴 한 토큰을 표준 요청 대화 상자에 전달하십시오 .

다른 경우에는 앱에서 더 이상 사용자 친구의 전체 목록을 검색 할 수 없습니다 (user_friends 권한을 사용하여 앱을 특별히 승인 한 친구 만 해당). 이것은 페이스 북에 의해 '디자인 상'으로 확인되었습니다.

사람들이 앱을 사용하도록 친구를 초대하도록 허용하려는 앱의 경우 웹에서 보내기 대화 상자 또는 iOS의 새 메시지 대화 상자Android .

업데이트 : Facebook은 이러한 변경 사항에 대해 FAQ를 게시했습니다. https://developers.facebook.com/docs/apps/faq 친구 등을 초대하기 위해 개발자가 사용할 수 있습니다.

625
Simon Cross

비록 사이먼 크로스의 대답은 받아 들여지고 정확합니다, 나는 그것을해야 할 일의 예 (안드로이드)로 조금 쇠고기 줄 알았는데. 내가 할 수있는대로 장군처럼 지키고 질문에만 집중할 것이다. 개인적으로 데이터베이스에 물건을 보관하여 로딩이 원활 해졌지만 CursorAdapter와 ContentProvider가 필요합니다. 범위는 약간 벗어났습니다.

나는 나 자신 여기에 왔고, 그 다음 생각했다, 지금 무엇?!

문제

user3594351 와 마찬가지로 친구 데이터가 비어 있다는 것을 알았습니다. FriendPickerFragment를 사용하여이 사실을 알았습니다. 3 개월 전에 효과가 있었던 것은 더 이상 작동하지 않습니다. 페이스 북의 예조차 깨졌습니다. 그래서 제 문제는 '어떻게 FriendPickerFragment를 손으로 만들 수 있습니까?

무엇이 작동하지 않았는가

옵션 # 1 Simon Cross 는 친구를 앱에 초대하기에 충분하지 않았습니다. Simon Cross 또한 요청 대화 상자를 권장했지만 한 번에 5 개의 요청 만 허용합니다. 요청 대화 상자에는 페이스 북에 로그인 한 동안 동일한 친구가 표시되었습니다. 유용하지 않다.

효과 (요약)

옵션 # 2와 노력. Facebook의 새로운 규칙을 반드시 이행해야합니다. 1. 게임입니다. 2. 캔버스 앱 (웹 존재)이 있습니다. 3.) 앱이 Facebook에 등록되어 있습니다. 모두 페이스 북 개발자 웹 사이트에서 설정 완료.

내 앱에서 친구 피커를 손으로 에뮬레이션하려면 다음을 수행했습니다.

  1. 두 조각을 보여주는 탭 활동을 만듭니다. 각 조각은 목록을 보여줍니다. 사용 가능한 친구 (/ me/friends)와 초대 할 수있는 친구 (/ me/invitable_friends)를위한 하나의 조각. 동일한 조각 코드를 사용하여 두 탭을 렌더링하십시오.
  2. Facebook에서 친구 데이터를 가져올 AsyncTask를 만듭니다. 해당 데이터가로드되면 값을 화면에 표시하는 어댑터로 던집니다.

세부 정보

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());
        }
    }
}
17
LEO

Facebook은 이제 정책을 수정했습니다. 앱에 Canvas 구현이없고 앱이 게임이 아닌 경우 전체 친구 목록을 가져올 수 없습니다. 물론 taggable_friends도 있지만 그 중 하나는 태그 지정 용입니다.

앱을 승인 한 친구 목록 만 가져올 수 있습니다.

그래프 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

희망이 도움이

12
Jobins John

Simon이 언급했듯이, 이것은 새로운 Facebook API에서는 가능하지 않습니다. 기술적으로 말하면 순수하게 브라우저 자동화를 통해 할 수 있습니다.

  • 이것은 Facebook 정책에 위배되므로 귀하가 거주하는 국가에 따라 합법적이지 않을 수 있습니다.
  • 당신은 자격 증명을 사용하거나 사용자에게 자격 증명을 요청해야하며 아마도 그들을 저장할 수도 있습니다 (대칭 암호화 된 암호를 저장하는 것은 좋은 생각이 아닙니다)
  • 페이 스북이 API를 바꿀 때 브라우저 자동화 코드도 업데이트해야합니다 (응용 프로그램의 업데이트를 강제로 수행 할 수없는 경우 브라우저 자동화를 웹 서비스로 가져와야합니다)
  • oAuth 개념을 우회하고 있습니다.
  • 반면에 내 느낌은 내 친구 목록을 포함하여 내 데이터를 소유하고있어 FB가 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 커넥터의 동적 업데이트가 가능합니다.

2
Ondrej Svejdar

Swift 4.2 및 Xcode 10.1에서

FB에서 친구 목록을 얻으려면 FB에서 검토 할 수 있도록 앱을 제출해야합니다. 일부 로그인 권한을 참조하십시오.

https://developers.facebook.com/docs/apps/review/login-permissions

여기에 두 단계

1) 우선 앱 상태는 실시간이어야 함

2) Get 필수 권한 FB 양식.

1) 앱 상태 라이브 사용 :

  1. 이동 앱 페이지을 선택

https://developers.facebook.com/apps/

  1. 대시 보드의 오른쪽 상단에서 상태를 선택하십시오.

 enter image description here

  1. 제출 개인 정보 취급 방침 url

 enter image description here

  1. 선택 카테고리

 enter image description here

  1. 이제 우리 앱이 실시간 상태

 enter image description here

완료 단계.

2) 검토를 위해 앱을 제출하십시오.

  1. 먼저 필요한 요청을 보냅니다.

예 : user_friends, user_videos, user_posts 등.

 enter image description here

  1. 두 번째 현재 요청 페이지로 이동

 enter image description here

예 : user_events

  1. 모든 세부 정보 제출

 enter image description here

  1. 이와 같이 모든 요청 (user_friends, user_events, user_videos, user_posts 등)을 제출하십시오.

  2. 마지막으로 검토를 위해 앱을 제출하십시오.

귀하의 검토가 FB 양식을 수락하면 귀하는 연락처 등을 읽을 자격이 있습니다.

2
iOS

/ me/taggable_friends? limit = 5000, 자바 스크립트 코드 사용

OR

그래프 API를 사용해보십시오.

https://graph.facebook.com/v2.3/user_id_here/taggable_friends?access_token=

재미있게 보내라.

2
Abhishek Sharma