373 votes

Facebook Graph Api v2.0 + - / moi / amis retourne vide, ou seulement les amis qui utilisent aussi mon application

J'essaie d'obtenir mon nom d'ami et mes identifiants avec le graphe api v2.0, mais les données sont 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<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!

633voto

Simon Cross Points 5436

Dans la v2.0 de l'API Graphique, appelant /me/friends renvoie la personne à des amis qui ont aussi l'utilisation de l'application.

En outre, dans la v2.0, vous devez demander l' user_friends la permission de chaque utilisateur. user_friends n'est plus inclus par défaut dans chaque connexion. Chaque utilisateur doit accorder à l' user_friends autorisation pour figurer dans la réponse à l' /me/friends. Voir la Facebook guide de mise à niveau pour des renseignements plus détaillés, consultez le résumé ci-dessous.

Si vous souhaitez accéder à une liste de non-application-à l'aide d'amis, il y a deux options:

  1. Si vous voulez laisser votre étiquette de leurs amis dans les histoires qu'ils publient à Facebook à l'aide de votre Application, vous pouvez utiliser l' /me/taggable_friends API. L'utilisation de ce paramètre nécessite un examen par Facebook et doit être utilisé uniquement pour le cas où vous êtes rendu à une liste d'amis afin de permettre à l'utilisateur de marquer dans un post.

  2. Si votre Application est un Jeu ET votre Jeu prend en charge Facebook Toile, vous pouvez utiliser l' /me/invitable_friends d'extrémité afin de rendre une invitation personnalisée boîte de dialogue, puis passer les jetons retourné par cette API pour les Requêtes standard boîte de Dialogue.

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 ceux des amis qui ont expressément autorisé de votre application à l'aide de l' user_friends autorisation). Ceci a été confirmé par Facebook comme "by design".

Pour les applications qui veulent permettre à des personnes à inviter des amis à utiliser l'application, vous pouvez toujours utiliser la boite de Dialogue d'envoi sur le Web ou la nouvelle boîte de Dialogue de Message sur iOS et Android.

Mise à JOUR: Facebook ont publié une foire aux questions sur ces changements ici: https://developers.facebook.com/docs/apps/faq ce qui explique toutes les options disponibles pour les développeurs afin d'inviter des amis etc.

17voto

LEO Points 526

Bien que Simon de la Croix - réponse est acceptée et correct, je pensais que je le boeuf un peu avec un exemple (android) de ce qui doit être fait. Je vais le garder comme général comme je peux et de se concentrer sur la question. Personnellement, je me suis retrouvé entreposer des objets dans une base de données de sorte que le chargement était lisse, mais qui nécessite un CursorAdapter et ContentProvider qui est un peu hors de portée ici.

Je suis venu ici moi-même pensé, maintenant ce qui?!

La Question

Tout comme user3594351, j'ai remarqué de l'ami de données est vide. J'ai trouvé ceci en utilisant le FriendPickerFragment. Ce qui a fonctionné il y a trois mois, ne fonctionne plus. Même facebook les exemples de cassé. Donc ma question était de savoir " Comment puis-je créer FriendPickerFragment à la main?

Ce Qui N'A Pas De Travail

Option #1 de Simon de la Croix n'était pas assez fort pour inviter des amis à l'application. Simon Croix a également recommandé à la Demande de Dialogue, mais qui ne permettent seulement 5 demandes à la fois. Les demandes de dialogue a également montré les mêmes amis pendant tout Facebook enregistré dans la session. Pas utile.

Ce Qui A Fonctionné (Résumé)

Option #2 avec un peu de travail acharné. Vous devez assurez-vous de remplir Facebook de nouvelles règles: 1.) Vous êtes un jeu 2.) Vous avez une Toile d'application (Présence sur le Web) 3.) Vous êtes à l'application est enregistrée avec Facebook. Tout est fait sur Facebook développeur de site web, sous paramètres.

Pour émuler l'ami sélecteur à la main à l'intérieur de mon application, j'ai fait la suivante:

  1. Créer un onglet activité qui montre deux fragments. Chaque fragment montre une liste. Un fragment de friend (/me/amis) et un autre pour invitable amis (/me/invitable_friends). Utiliser le même fragment de code pour rendre les deux onglets.
  2. Créer un AsyncTask qui sera l'ami de données de Facebook. Une fois que les données sont chargées, de le jeter à l'adaptateur qui va rendre les valeurs à l'écran.

Détails

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

Le FacebookFriend classe 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());
        }
    }
}

2voto

Ondrej Svejdar Points 5039

Comme Simon mentionné, ce n'est pas possible dans les nouveaux facebook API. Vous pouvez utiliser le navigateur de l'automatisation comme une solution de contournement.

Inconvénients:

  • vous devrez demander à l'utilisateur pour ses informations d'identification directement (et, éventuellement, de les stocker sur votre côté)
  • quand facebook changements de leur api, vous aurez à mettre à jour le navigateur de l'automatisation de code (si vous ne pouvez pas forcer les mises à jour de votre application, vous devez placer le navigateur automatisation de la pièce comme webservice)
  • c'est en contournant OAuth concept, en tant qu'utilisateur aura relais sur vous pour stocker/manipuler les informations d'identification de manière sécurisée
  • c'est contre le Facebook de la politique (mais puisque vous avez le nom d'utilisateur/mot de passe vous n'avez pas de soins sur facebook politiques)

Avantage:

  • actuellement, il n'existe pas d'autre manière d'obtenir la liste de tous les amis
  • ce n'est pas différent de ce que facebook fait quand ils obtiennent la liste de tous vos contacts à partir de votre compte de messagerie
  • si un grand nombre de développeurs de commencer à l'utiliser, il pourrait donner facebook une bonne santé pousser à le replacer dans l'API Open Graph

Exemple de mise en œuvre à l'aide de WatiN (il y a des points à affiner - faites défiler vers le bas pour obtenir tous les contacts, par exemple)

class FacebookUser
{
  public string Name { get; set; }
  public long Id { get; set; }
}

using (var browser = new IE("https://www.facebook.com"))
{
  try
  {
    browser.TextField(Find.ByName("email")).Value = "your fb username";
    browser.TextField(Find.ByName("pass")).Value = "your fb 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 users = new List<FacebookUser>();
  var links = browser.Links.Where(l => l.GetAttributeValue("data-hovercard") != null 
    && l.GetAttributeValue("data-hovercard").Contains("user.php")
    && l.Text != null
  ).ToList();
  Regex 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
    });
  }
}

-5voto

Billy A Points 56

Je ne sais pas si elles ont changé cela ou non. Mais c’est la façon dont j’ai toujours toutes mes données de l’utilisateur un ami. Même ceux qui n’utilise pas l’app.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X