Facebook Graph API v2.0 + – / moi / amis retourne vide ou uniquement les amis qui utilisent également mon application

J’essaie d’obtenir mon nom et mes identifiants d’amis avec Graph API v2.0, mais les données retournent vides:

{ "data": [ ] } 

Quand j’utilisais la version 1.0, tout allait bien 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* friend in friends) { NSLog(@"I have a friend named %@ with id %@", friend.name, friend.id); } }]; 

Mais maintenant, je ne peux pas avoir d’amis!

    Dans la version 2.0 de l’API Graph, l’appel de /me/friends renvoie les /me/friends la personne qui utilisent également l’application.

    De plus, dans la version user_friends , vous devez demander l’autorisation user_friends à chaque utilisateur. user_friends n’est plus inclus par défaut dans chaque connexion. Chaque utilisateur doit accorder l’autorisation user_friends pour apparaître dans la réponse à /me/friends . Consultez 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 qui n’utilisent pas d’application, deux options s’offrent à vous:

    1. Si vous souhaitez laisser vos collaborateurs étiqueter leurs amis dans des histoires qu’ils publient sur Facebook à l’aide de votre application, vous pouvez utiliser l’API /me/taggable_friends . L’utilisation de ce noeud final nécessite un examen par Facebook et ne doit être utilisé que dans le cas où vous publiez une liste d’amis afin de permettre à l’utilisateur de les marquer dans un message.

    2. Si votre application est un jeu ET que votre jeu prend en charge Facebook Canvas , vous pouvez utiliser le sharepoint terminaison /me/invitable_friends pour afficher une boîte de dialog d’invitation personnalisée , puis transmettre les jetons renvoyés par cette API au dialog de requête standard.

    Dans d’autres cas, les applications ne peuvent plus récupérer la liste complète des amis d’un utilisateur (uniquement les amis qui ont spécifiquement autorisé votre application à l’aide de l’autorisation user_friends ). Cela a été confirmé par Facebook comme étant «à dessein».

    Pour les applications qui permettent d’inviter des amis à utiliser une application, vous pouvez toujours utiliser la boîte de dialog Envoyer sur le Web ou le nouveau dialog de message sur iOS et Android .

    MISE À JOUR: Facebook a publié une FAQ sur ces changements ici: https://developers.facebook.com/docs/apps/faq qui explique toutes les options disponibles aux développeurs pour inviter des amis, etc.

    Bien que la réponse de Simon Cross soit acceptée et correcte, j’ai pensé que je mettrais un peu plus en évidence un exemple (android) de ce qui doit être fait. Je vais le garder aussi général que possible et me concentrer uniquement sur la question. Personnellement, je me suis retrouvé à stocker des choses dans une firebase database pour que le chargement soit fluide mais cela nécessite un CursorAdapter et un ContentProvider qui sont un peu hors de scope ici.

    Je suis venu ici moi-même et j’ai alors pensé, et maintenant?!

    Le problème

    Tout comme user3594351 , je remarquais que les données des amis étaient vides. Je l’ai découvert en utilisant FriendPickerFragment. Ce qui a fonctionné il y a trois mois ne fonctionne plus. Même les exemples de facebook ont ​​éclaté. Donc, mon problème était «Comment créer FriendPickerFragment à la main?

    Ce qui n’a pas fonctionné

    L’option # 1 de Simon Cross n’était pas assez forte pour inviter des amis à l’appli. Simon Cross a également recommandé le dialog Demandes, mais cela ne permettrait que 5 demandes à la fois. La boîte de dialog Demandes a également montré les mêmes amis lors d’une session donnée sur Facebook. Pas utile.

    Ce qui a fonctionné (résumé)

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

    Pour émuler le sélecteur d’amis à la main dans mon application, j’ai fait ce qui suit:

    1. Créez une activité d’onglet qui montre deux fragments. Chaque fragment montre une liste. Un fragment pour un ami disponible (/ me / friends) et un autre pour des amis invitables (/ me / invitable_friends). Utilisez le même code de fragment pour afficher les deux tabs.
    2. Créez une AsyncTask qui récupérera les données d’amis de Facebook. Une fois que ces données sont chargées, lancez-les sur l’adaptateur qui rendra les valeurs à l’écran.

    Détails

    La AsynchTask

     private class DownloadFacebookFriendsTask extends AsyncTask { private final Ssortingng TAG = DownloadFacebookFriendsTask.class.getSimpleName(); GraphObject graphObject; ArrayList myList = new ArrayList(); @Override protected Boolean doInBackground(FacebookFriend.Type... pickType) { // //Determine Type // Ssortingng 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.toSsortingng()); } 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 { Ssortingng facebookId; Ssortingng name; Ssortingng 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.getSsortingng("id"); this.name = jsonObject.getSsortingng("name"); //Handle the picture data. JSONObject pictureJsonObject = jsonObject.getJSONObject("picture").getJSONObject("data"); boolean isSilhouette = pictureJsonObject.getBoolean("is_silhouette"); if (!isSilhouette) { this.pictureUrl = pictureJsonObject.getSsortingng("url"); } else { this.pictureUrl = ""; } this.invitable = true; } else { //parse /me/friends this.facebookId = jsonObject.getSsortingng("id"); this.name = jsonObject.getSsortingng("name"); this.available = true; this.pictureUrl = ""; } isValid = true; } catch (JSONException e) { Log.w("#", "Warnings - unable to process FB JSON: " + e.getLocalizedMessage()); } } } 

    Facebook a révisé ses politiques maintenant. Vous ne pouvez pas obtenir l’intégralité de la liste d’amis si votre application ne dispose pas d’une 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 destiné uniquement au marquage.

    Vous pourrez extraire la liste des amis qui ont autorisé l’application uniquement.

    Les applications qui utilisent Graph API 1.0 fonctionneront jusqu’au 30 avril 2015, après quoi 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

    Comme Simon l’a mentionné, ce n’est pas possible dans la nouvelle API facebook. Pure techniquement parlant, vous pouvez le faire via l’automatisation du navigateur.

    • c’est contre la politique de Facebook, donc en fonction du pays où vous vivez, cela peut ne pas être légal
    • vous devrez utiliser vos informations d’identification / demander à l’utilisateur des informations d’identification et les stocker éventuellement (stocker des mots de passe même chiffrés de manière symésortingque n’est pas une bonne idée)
    • Lorsque Facebook change 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 mettre l’automatisation du navigateur au service Web).
    • c’est contourner le concept OAuth
    • D’un autre côté, mon sentiment est que je possède mes données, y compris la liste de mes amis et FB ne devrait pas m’empêcher d’accéder à ces données via une API.

    Exemple d’implémentation utilisant WatiN

     class FacebookUser { public ssortingng Name { get; set; } public long Id { get; set; } } public IList GetFacebookFriends(ssortingng email, ssortingng password, int? maxTimeoutInMilliseconds) { var users = new List(); 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.GetAtsortingbuteValue("data-hovercard") != null && l.GetAtsortingbuteValue("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.GetAtsortingbuteValue("data-hovercard") != null && l.GetAtsortingbuteValue("data-hovercard").Contains("user.php") && l.Text != null ).ToList(); var idRegex = new Regex("id=(?([0-9]+))"); foreach (var link in links) { ssortingng hovercard = link.GetAtsortingbuteValue("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 Cela permet également la mise à jour dynamic du connecteur facebook qui récupère la liste de vos contacts.

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

    OU

    essayez l’API graphique

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

    S’amuser

    dans FBSDKGraphAPI version 2.0 ou supérieure, vous devez demander à chaque utilisateur la permission user_friends au moment de la connexion FB. Étant donné que user_friends n’est plus inclus par défaut dans chaque connexion, nous devons l’append. Chaque utilisateur doit accorder l’autorisation user_friends pour apparaître dans la réponse à / moi / amis

      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 { } } } 

    Donc, au moment de la connexion au FB, l’écran d’invite contient toutes les permissions entrer la description de l'image ici

    Si l’utilisateur appuie sur le bouton Continuer, les permissions seront définies. Lorsque vous accédez à la liste d’amis en utilisant FBGraphAPI, vos amis qui se sont connectés à l’application comme ci-dessus seront répertoriés.

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

    La sortie contiendra les utilisateurs qui ont accordé l’autorisation user_friends au moment de la connexion à votre application via Facebook.

     { data = ( { id = xxxxxxxxxx; name = "xxxxxxxx"; } ); paging = { cursors = { after = xxxxxx; before = xxxxxxx; }; }; summary = { "total_count" = 8; }; }