web-dev-qa-db-fra.com

Facebook Graph API v2.0 + - / me / friends renvoie vide, ou uniquement les amis qui utilisent également mon application

J'essaie d'obtenir le nom et les identifiants de mes amis avec Graph API v2.0, mais les données renvoyées sont vides:

{
  "data": [
  ]
}

Lorsque j'utilisais la version 1.0, tout était OK avec la requête suivante:

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

Mais maintenant je ne peux pas avoir d'amis!

365
Kaslico

Dans la v2.0 de l'API Graph, l'appel de /me/friends renvoie les amis de la personne qui utilisent également l'application.

En outre, dans la version 2.0, vous devez demander l'autorisation user_friends à chaque utilisateur. user_friends n'est plus inclus par défaut à chaque connexion. Chaque utilisateur doit accorder le droit user_friends pour apparaître dans la réponse à /me/friends. Voir le guide de mise à niveau Facebook pour plus d'informations, ou consultez le résumé ci-dessous.

Si vous souhaitez accéder à une liste d'amis n'utilisant pas d'application, vous avez le choix entre deux options:

  1. Si vous souhaitez laisser vos contacts taguer leurs amis dans des articles qu'ils publient sur Facebook à l'aide de votre application , vous pouvez utiliser l’API /me/taggable_friends. L'utilisation de ce terminal nécessite une révision de Facebook et ne doit être utilisée que dans le cas où vous rendez une liste d'amis afin de permettre à l'utilisateur de les taguer dans un message.

  2. Si votre application est un jeu ET que votre jeu prend en charge Facebook Canvas, vous pouvez utiliser le /me/invitable_friends endpoint afin de rendre une boîte de dialogue d'invitation personnalisée , puis transmettez les jetons renvoyés par cette API à la boîte de dialogue standard Requests.

Dans d'autres cas, les applications ne sont plus en mesure de récupérer la liste complète des amis d'un utilisateur (uniquement les amis qui ont spécifiquement autorisé votre application en utilisant l'autorisation user_friends). Cela a été confirmé par Facebook comme étant "de par leur conception".

Pour les applications qui souhaitent autoriser les personnes à inviter leurs amis à utiliser une application, vous pouvez toujours utiliser le Boîte de dialogue d'envoi sur le Web ou le nouveau Message Dialogue sur iOS et Android .

MISE À JOUR: Facebook a publié un FAQ sur ces modifications: https: //developers.facebook.com/docs/apps/faq qui explique toutes les options. disponible pour les développeurs afin d'inviter des amis, etc.

625
Simon Cross

Bien que la réponse de de Simon Cross soit acceptée et correcte, je pensais que je renforcerais un peu cet exemple avec un exemple (Android) de ce qui doit être fait. Je vais le garder aussi général que possible et me concentrer sur la question. Personnellement, j'ai fini par stocker des éléments dans une base de données afin que le chargement se déroule sans heurts, mais cela nécessite un CursorAdapter et un ContentProvider, ce qui est un peu hors de portée ici.

Je suis venu ici moi-même et puis pensé, maintenant quoi?!

Le problème

Tout comme user3594351 , je remarquais que les données de l'ami étaient vierges. J'ai découvert cela en utilisant FriendPickerFragment. Ce qui a fonctionné il y a trois mois ne fonctionne plus. Même les exemples de facebook ont ​​éclaté. Mon problème était donc "Comment créer FriendPickerFragment à la main?

Ce qui n'a pas fonctionné

L'option n ° 1 de Simon Cross n'était pas assez puissante pour inviter des amis à l'application. Simon Cross a également recommandé la boîte de dialogue Demandes, mais ne permet que 5 demandes à la fois. La boîte de dialogue Demandes a également montré les mêmes amis au cours de toute session ouverte avec Facebook. Pas utile.

Ce qui a fonctionné (Résumé)

Option n ° 2 avec un travail acharné. Vous devez vous assurer de respecter les nouvelles règles de Facebook: 1.) Vous êtes un jeu 2.) Vous avez une application Canvas (Présence Web) 3.) Votre application est enregistrée avec Facebook. Tout est fait sur le site Web des développeurs Facebook sous les paramètres.

Pour émuler le sélecteur d'amis à la main dans mon application, j'ai procédé comme suit:

  1. Créez une activité de l'onglet qui montre deux fragments. Chaque fragment montre une liste. Un fragment pour les amis disponibles (/ moi/amis) et un autre pour les amis invitables (/ moi/invitable_friends). Utilisez le même code de fragment pour rendre les deux onglets.
  2. Créez une tâche asynchrone qui récupérera les données des amis de Facebook. Une fois ces données chargées, envoyez-les à l’adaptateur qui restituera les valeurs à l’écran.

Détails

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

La classe FacebookFriend que j'ai créée

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 a révisé ses politiques maintenant. De toute façon, vous ne pouvez pas obtenir toute la liste d'amis si votre application n'a pas d'implémentation Canvas et si votre application n'est pas un jeu. Bien sûr, il y a aussi taggable_friends, mais celui-ci est réservé au marquage.

Vous serez en mesure de tirer la liste des amis qui ont autorisé l'application seulement.

Les applications qui utilisent Graph API 1.0 fonctionneront jusqu'au 30 avril 2015 et par la suite, elles seront obsolètes.

Voir le lien ci-dessous pour obtenir plus de détails à ce sujet

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

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

J'espère que cela t'aides

12
Jobins John

Comme Simon l'a mentionné, cela n'est pas possible dans la nouvelle API de Facebook. Pur techniquement parlant vous pouvez le faire via l'automatisation du navigateur.

  • c'est contre la politique de Facebook, donc selon le pays où vous vivez, cela peut ne pas être légal
  • vous devrez utiliser vos informations d'identification/demander à l'utilisateur pour les informations d'identification et éventuellement les stocker (stocker des mots de passe même cryptés de manière symétrique n'est pas une bonne idée)
  • lorsque facebook modifie son api, vous devrez également mettre à jour le code d'automatisation du navigateur (si vous ne pouvez pas forcer les mises à jour de votre application, vous devez configurer la fonction d'automatisation du navigateur en tant que service Web).
  • c'est contourner OAuth concept
  • d'autre part, mon sentiment est que je possède mes données, y compris la liste de mes amis et que FB ne devrait pas m'empêcher d'y accéder via l'API.

Exemple d'implémentation utilisant 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;
}

Prototype avec la mise en œuvre de cette approche (en utilisant C #/Watin) voir https://github.com/svejdo1/ShadowApi Il permet également la mise à jour dynamique du connecteur facebook qui récupère la liste de vos contacts.

2
Ondrej Svejdar

Dans Swift 4.2 et Xcode 10.1

Si vous souhaitez obtenir la liste d'amis de FB, vous devez soumettre votre application à la révision dans FB. Voir certaines des autorisations de connexion.

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

Ici deux étapes

1) Tout d'abord, votre statut d'application doit être en direct .

2) Obtenir les autorisations requises sous forme de FB.

1) Activer notre statut d'application en direct:

  1. Allez sur la page des applications et sélectionnez votre application

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

  1. Sélectionnez le statut en haut à droite dans Tableau de bord .

enter image description here

  1. Soumettez l'URL de la politique de confidentialité

enter image description here

  1. Sélectionnez la catégorie

enter image description here

  1. Maintenant, notre application est en statut .

enter image description here

Sur l'étape terminée.

2) Soumettez notre application pour examen:

  1. Envoyez d'abord les demandes requises.

Ex: user_friends, user_videos, user_posts etc.

enter image description here

  1. Deuxième aller à la page de la demande actuelle

enter image description here

Ex: événements_utilisateur

  1. Soumettre tous les détails

enter image description here

  1. Comme ceci, soumettez toutes les demandes (user_friends, user_events, user_videos, user_posts, etc.).

  2. Enfin, soumettez votre application pour examen.

Si votre avis a accepté le formulaire FB, vous êtes maintenant éligible pour lire des contacts, etc.

2
iOS

Essayez/me/taggable_friends? Limit = 5000 en utilisant votre code javascript

OR

essayez l'API graphique

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

S'amuser

2
Abhishek Sharma