Facebook Graph API v2. 0 + - /me / friends zwraca pustą lub tylko znajomych, którzy również korzystają z mojej aplikacji

Próbuję pobrać nazwę i identyfikatory znajomego z Graph API v2. 0, ale dane zwracają puste:

{
  "data": [
  ]
}

Kiedy używałem v1. 0, wszystko było OK z następującym żądaniem:

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);
    }
}];
Ale teraz nie mogę zdobyć przyjaciół!
Author: Peter Mortensen, 2014-05-02

6 answers

W wersji 2.0 API Graph wywołanie /me/friends zwraca znajomych osoby, która również korzysta z aplikacji.

Dodatkowo, w wersji 2.0, musisz zażądać pozwolenia user_friends od każdego użytkownika. user_friends nie jest już domyślnie uwzględniany przy każdym logowaniu. Każdy użytkownik musi przyznać pozwolenie user_friends, aby pojawić się w odpowiedzi na /me/friends. Zobacz Facebook upgrade guide aby uzyskać bardziej szczegółowe informacje lub przejrzyj podsumowanie poniżej.

Jeśli chcesz uzyskać dostęp do listy znajomych, którzy nie używają aplikacji, istnieją dwie opcje:

  1. Jeśli chcesz, aby Twoi ludzie tagowali swoich przyjaciół w historiach, które publikują na Facebook ' u za pomocą Twojej aplikacji, możesz użyć API /me/taggable_friends. użycie tego punktu końcowego wymaga przeglądu przez Facebook i powinno być używane tylko w przypadku, gdy renderujesz listę znajomych, aby użytkownik mógł oznaczyć je w poście.

  2. Jeśli Twoja aplikacja jest grą i gra obsługuje Płótno Facebook, możesz użyć aby renderować własne okno dialogowe zaproszeń , następnie przekazać tokeny zwracane przez ten interfejs API do standardowego okna dialogowego żądań.

W innych przypadkach aplikacje nie są już w stanie pobrać pełnej listy znajomych użytkownika (tylko tych znajomych, którzy specjalnie autoryzowali Twoją aplikację za pomocą zezwolenia user_friends). [39]}Facebook potwierdził to jako "według projektu".

Dla aplikacji, które chcą umożliwić ludziom Zapraszanie znajomych do korzystania z aplikacji, możesz nadal używać Wyślij okno dialogowe Na Web lub nowe okno dialogowe wiadomości na iOS i Android.

Aktualizacja: Facebook opublikował FAQ na temat tych zmian tutaj: https://developers.facebook.com/docs/apps/faq które wyjaśniają wszystkie opcje dostępne dla programistów, aby zaprosić znajomych itp.

 617
Author: Simon Cross,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-06 20:41:43

Chociaż odpowiedź Simona Crossa jest akceptowana i poprawna, pomyślałem, że trochę ją wzmocnię przykładem (android) tego, co należy zrobić. Zachowam to tak ogólnie, jak tylko mogę i skupię się na pytaniu. Osobiście skończyłem przechowywanie rzeczy w bazie danych, więc ładowanie było płynne, ale to wymaga CursorAdapter i ContentProvider, który jest nieco poza zakresem tutaj.

Przyszedłem tu sam i pomyślałem, co teraz?!

Problem

Po prostu podobnie jak user3594351 , zauważyłem, że dane znajomego są puste. Znalazłem to za pomocą FriendPickerFragment. To, co działało trzy miesiące temu, już nie działa. Nawet przykłady facebook ' a pękły. Więc mój problem był "jak utworzyć FriendPickerFragment ręcznie?

Co Nie Działa

Opcja # 1 z Simon Cross nie była wystarczająco silna, aby zaprosić znajomych do aplikacji. Simon Cross również polecił okno żądań, ale to pozwoli tylko na 5 prośby na raz. Okno dialogowe zapytań pokazywało również tych samych znajomych podczas danej sesji zalogowanego Facebook ' a. Bezużyteczne.

Co Zadziałało (Podsumowanie)

Opcja # 2 z ciężką pracą. Musisz upewnić się, że spełniasz nowe zasady Facebook ' a: 1./ Align = "left" / ) Masz aplikację Canvas (obecność w sieci) 3.) Twoja aplikacja jest zarejestrowana w Facebook. Wszystko odbywa się na stronie dewelopera Facebook w Ustawieniach.

Aby emulować znajomego picker ręcznie wewnątrz mojej aplikacji zrobiłem "following": {]}

  1. Utwórz działanie tabulatora, które pokazuje dwa fragmenty. Każdy fragment pokazuje listę. Jeden fragment dla dostępnego przyjaciela (/me / friends) i drugi dla zaproszonych przyjaciół (/me / invitable_friends). Użyj tego samego kodu fragmentu do renderowania obu kart.
  2. Utwórz AsyncTask, który pobierze dane znajomego z Facebook. Po załadowaniu danych wrzuć je do adaptera, który wyrenderuje wartości na ekran.

Szczegóły

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

Klasa FacebookFriend, którą stworzyłem

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());
        }
    }
}
 18
Author: LEO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-30 02:19:20

Facebook zmienił teraz swoje zasady. Nie możesz uzyskać całej listy znajomych, jeśli Twoja aplikacja nie ma implementacji Canvas i jeśli Twoja aplikacja nie jest grą. Oczywiście istnieje również taggable_friends, ale ten służy tylko do tagowania.

Będziesz mógł pobrać listę znajomych, którzy autoryzowali tylko aplikację.

Aplikacje korzystające z Graph API 1.0 będą działać do 30 kwietnia 2015 roku, a następnie zostaną wycofane.

Zobacz link poniżej, aby uzyskać więcej szczegóły na ten temat

Https://developers.facebook.com/docs/graph-api/reference/v2.2/user/friends

Https://developers.facebook.com/docs/apps/faq#invite_to_app

Hope this helps

 12
Author: Jobins John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-21 11:54:54

Jak wspomniał Simon, nie jest to możliwe w nowym API facebook. czysto technicznie {[3] } można to zrobić poprzez automatyzację przeglądarki.

    Jest to niezgodne z Polityką Facebook, więc w zależności od kraju, w którym mieszkasz, może to nie być legalne]}
  • będziesz musiał użyć swoich poświadczeń / poprosić Użytkownika o poświadczenia i ewentualnie je przechowywać (przechowywanie haseł nawet symetrycznie zaszyfrowanych nie jest dobrym pomysłem)
  • gdy facebook zmieni swoje api, będziesz musiał zaktualizować przeglądarkę kod automatyzacji również (jeśli nie możesz wymusić aktualizacji aplikacji, powinieneś umieścić automatyzację przeglądarki jako webservice)
  • to omija koncepcję OAuth
  • z drugiej strony mam wrażenie, że posiadam swoje dane, w tym listę moich znajomych, a FB nie powinno ograniczać mi dostępu do nich przez API

Przykładowa implementacja za pomocą 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;
}

Prototyp z implementacją tego podejścia (przy użyciu C#/Watin) zobacz https://github.com/svejdo1/ShadowApi Umożliwia również dynamiczną aktualizację złącza facebook, który pobiera listę kontaktów.

 1
Author: Ondrej Svejdar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 19:28:33

Try / me / taggable_friends?limit = 5000 przy użyciu kodu javascript

LUB

Wypróbuj graficzne API

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

Baw się dobrze

 0
Author: Abhishek Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-22 14:53:43

W FBSDKGraphAPI v2. 0 lub nowszym, musisz poprosić każdego użytkownika o pozwolenie user_friends w czasie logowania na FB.ponieważ user_friends nie jest już domyślnie uwzględniany przy każdym logowaniu, musimy to dodać. Każdy użytkownik musi przyznać uprawnienia user_friends, aby pojawić się w odpowiedzi na /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 {
            }
        }
    }

Więc w momencie logowania na FB, wyświetla monit, który zawiera wszystkie uprawnieniaTutaj wpisz opis obrazka

Jeśli użytkownik naciśnie przycisk Kontynuuj, zostaną ustawione uprawnienia. Kiedy uzyskasz dostęp do listy znajomych za pomocą FBGraphAPI, Twoi znajomi, którzy zalogowali się do aplikacji, jak powyżej, zostaną wymienieni

   if((FBSDKAccessToken.current()) != nil){
        FBSDKGraphRequest(graphPath: "/me/friends", parameters: ["fields" : "id,name"]).start(completionHandler: { (connection, result, error) -> Void in
            if (error == nil){

                print(result!)
            }
        })
    }

Wynik będzie zawierał użytkowników, którzy przyznali uprawnienia user_friends w momencie logowania się do aplikacji za pośrednictwem Facebook

{
    data =     (
                {
            id = xxxxxxxxxx;
            name = "xxxxxxxx";
        }
    );
    paging =     {
        cursors =         {
            after = xxxxxx;
            before = xxxxxxx;
        };
    };
    summary =     {
        "total_count" = 8;
    };
}
 -1
Author: Lineesh K Mohan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-27 07:20:42