Facebook Graph API v2. 0+ - /me / friends возвращает пустые или только друзья, которые также используют мое приложение
Я пытаюсь получить имя моего друга и идентификаторы с Graph API v2. 0, но данные возвращаются пустыми:
{
"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);
}
}];
но теперь я не могу найти друзей!
6 ответов:
в версии 2.0 API Graph, вызов
/me/friends
возвращает друзей человека, которые также используют приложения.кроме того, в версии 2.0, вы должны запросить
user_friends
разрешение от каждого пользователя.user_friends
больше не включается по умолчанию при каждом входе. Каждый пользователь должен предоставитьuser_friends
разрешение для того, чтобы появиться в ответе на/me/friends
. Смотрите руководство по обновлению Facebook для получения более подробной информации, или обзор резюме ниже.если вы хотите получить доступ список друзей, не использующих приложение, есть два варианта:
если вы хотите, чтобы ваши люди тэг своих друзей в историях, которые они публикуют на Facebook с помощью вашего приложения, вы можете использовать
/me/taggable_friends
API. использование этой конечной точки требует рассмотрения Facebook и должен использоваться только в том случае, когда вы отображаете список друзей, чтобы позволить пользователю пометить их в a должность.если ваше приложение является игрой и ваша игра поддерживает Facebook Canvas можно использовать
/me/invitable_friends
конечная точка для того, чтобы сделать пользовательский диалог приглашения, затем передайте токены, возвращенные этим API в стандартный диалог запросов.в других случаях приложения больше не могут получить полный список друзей пользователя (только те друзья, которые специально авторизация вашего приложения с помощью
user_friends
разрешения). это было подтверждено Facebook как "по дизайну".для приложений, желающих разрешить людям приглашать друзей использовать приложение, вы все равно можете использовать отправить диалог в Интернете или новый диалоговое окно сообщения на iOS и Android.
обновление: Facebook опубликовал FAQ по этим изменениям здесь:https://developers.facebook.com/docs/apps/faq который объясните все варианты, доступные разработчикам, чтобы пригласить друзей и т. д.
хотя Саймона Кросса ответ принят и правильный, я думал, что я бы немного увеличил его с примером (android) того, что нужно сделать. Я постараюсь сделать это как можно более общим и сосредоточусь только на вопросе. Лично я закончил хранение вещей в базе данных, поэтому загрузка была гладкой, но для этого требуется CursorAdapter и ContentProvider, который немного выходит за рамки здесь.
Я сам пришел сюда и потом подумал, А что теперь?!
в Выпуск
как user3594351, Я заметил, что данные друга были пустыми. Я узнал это с помощью FriendPickerFragment. То, что работало три месяца назад, больше не работает. Даже примеры facebook сломались. Итак, мой вопрос был "как я могу создать FriendPickerFragment вручную?
Что Не Получилось
Вариант №1 от Симон Крест не было достаточно сильным, чтобы пригласить друзей в приложение. Симон Крест также рекомендуется Диалог запросов, но это позволит только 5 запросов одновременно. Диалог запросов также показывал одних и тех же друзей во время любого сеанса входа в систему Facebook. Не полезный.
Что Сработало (Резюме)
Вариант №2 с некоторой тяжелой работой. Вы должны убедиться, что вы выполняете новые правила Facebook: 1.) Ты игра 2.) У вас есть приложение Canvas (веб-присутствие) 3.) Вы приложение зарегистрировано в Facebook. Все сделано на веб-сайте разработчика Facebook под настройки.
для эмуляции выбора друга вручную в моем приложении я сделал следующее:
- создайте действие вкладки, которое показывает два фрагмента. Каждый фрагмент показывает список. Один фрагмент для доступных друзей (/me/friends) и другой для приглашенных друзей (/me/invitable_friends). Используйте один и тот же фрагмент кода для отображения обеих вкладок.
- создайте AsyncTask, который будет получать данные о друзьях из Facebook. Как только эти данные будут загружены, бросьте их на адаптер, который отобразит значения на экране.
подробности
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); } } }
класс Facebook Bookfriend, который я создал
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()); } } }
Facebook пересмотрел свою политику в настоящее время. Вы не можете получить весь список друзей в любом случае, если ваше приложение не имеет реализации холста, и если ваше приложение не является игрой. Конечно, есть также taggable_friends,но это только для маркировки.
вы сможете вытащить список друзей, которые разрешили только приложение.
приложения, использующие Graph API 1.0, будут работать до 30 апреля 2015 года, и после этого он будет устарел.
посмотреть ссылке ниже, чтобы получить более подробную информацию об этом
https://developers.facebook.com/docs/graph-api/reference/v2.2/user/friends
https://developers.facebook.com/docs/apps/faq#invite_to_app
надеюсь, что это помогает
Как упоминал Саймон, это невозможно в новом API facebook. чисто с технической точки зрения вы можете сделать это с помощью автоматизации браузера.
- это против политики Facebook, так что в зависимости от страны, где вы живете это не может быть законным
- вам придется использовать свои учетные данные / запрашивать учетные данные пользователя и, возможно, хранить их (хранение паролей даже симметрично зашифрованных не является хорошей идеей)
- когда 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 connector, который извлекает список ваших контактов.
Try/me / taggable_friends?limit=5000 с помощью кода javascript
или
попробуйте graph API
https://graph.facebook.com/v2.3/user_id_here/taggable_friends?access_token=
удачи
в FBSDKGraphAPI версии 2.0 или выше, вы должны запросить разрешение user_friends от каждого пользователя во время входа в систему FB.поскольку user_friends больше не включается по умолчанию в каждый логин, мы должны добавить это. Каждый пользователь должен предоставить разрешение user_friends, чтобы появиться в ответе на /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 { } } }
поэтому во время входа в систему FB он запрашивает экран, который содержит все разрешения
если пользователь нажимает кнопку "Продолжить", то разрешения будут установлены. Когда вы получаете доступ к списку друзей с помощью FBGraphAPI, ваши друзья, которые вошли в приложение, как указано выше, будут перечислены
if((FBSDKAccessToken.current()) != nil){ FBSDKGraphRequest(graphPath: "/me/friends", parameters: ["fields" : "id,name"]).start(completionHandler: { (connection, result, error) -> Void in if (error == nil){ print(result!) } }) }
вывод будет содержать пользователей, которые предоставили user_friends разрешение на момент входа в приложение через Facebook
{ data = ( { id = xxxxxxxxxx; name = "xxxxxxxx"; } ); paging = { cursors = { after = xxxxxx; before = xxxxxxx; }; }; summary = { "total_count" = 8; }; }