Facebook Graph API v2.0 + - / me / friends boş döndürür veya yalnızca uygulamamı kullanan arkadaşlar


366

Grafik API v2.0 ile arkadaşımın adı ve kimlikleri almaya çalışıyorum, ancak veri boş döndürür:

{
  "data": [
  ]
}

V1.0 kullanırken, her şey aşağıdaki isteği ile Tamam oldu:

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

Ama şimdi arkadaş edinemiyorum!


bu sorunun olası bir üstesinden gelmek stackoverflow.com/a/25584013/2529087
java.quaso

Yanıtlar:


627

Graph API'sinin v2.0 sürümünde, çağrı /me/friends, uygulamayı kullanan kişinin arkadaşlarını döndürür.

Ayrıca, v2.0 sürümünde user_friendsher kullanıcının iznini istemelisiniz . user_friendsartık her girişte varsayılan olarak bulunmuyor. user_friendsYanıt olarak görünmesi için her kullanıcının izin vermesi gerekir /me/friends. Daha ayrıntılı bilgi için Facebook yükseltme kılavuzuna bakın veya aşağıdaki özeti inceleyin.

Uygulama kullanmayan arkadaşların listesine erişmek istiyorsanız, iki seçenek vardır:

  1. Çalışanlarınızın, uygulamanızı kullanarak Facebook'ta yayınladıkları hikayelerde arkadaşlarını etiketlemelerine izin vermek istiyorsanız ,/me/taggable_friendsAPI'yıkullanabilirsiniz. Bu uç noktanın kullanımı Facebook tarafından incelenmeyi gerektirir ve yalnızca kullanıcının bir yayında etiketlemesine izin vermek için bir arkadaş listesi oluşturduğunuz durumda kullanılmalıdır.

  2. Uygulamanız bir Oyunsa ve Oyununuz Facebook Canvas'ı destekliyorsa ,/me/invitable_friendsişlemekiçinbitiş noktasınıkullanabilirsiniz. özel bir davet iletişim kutusu , ardından bu API tarafından döndürülen simgeleri standart İstekler İletişim Kutusuna iletebilirsiniz .

Diğer durumlarda, uygulamalar artık bir kullanıcının arkadaşlarının tam listesini alamaz (yalnızca user_friendsizninizi kullanarak uygulamanıza özel olarak yetkilendirilmiş olan arkadaşlar ). Bu Facebook tarafından 'tasarım' olarak onaylandı.

Kullanıcıların bir uygulamayı kullanmak için arkadaşlarını davet etmesine izin vermek isteyen uygulamalar için yine de Web'de Gönder İletişim Kutusunu veya iOS'ta yeni İleti İletişim Kutusunu kullanabilirsiniz ve Android'de .

GÜNCELLEME: Facebook, bu değişiklikler hakkında bir SSS yayınladı: https://developers.facebook.com/docs/apps/faq , arkadaşlarını davet etmek için geliştiricilerin kullanabileceği tüm seçenekleri açıklayan.


Son düzenlemenizden bu yana haber var mı yoksa aynı sayfada mıyız?
Ilya Gazman

taggable_friendsİnceleme gönderimi için öğelerde göremiyorum .
AlikElzin-kilaka

7
Neden bu kadar kısıtlamak zorunda olduklarını anlayamıyorum. Demek istediğim eski sistem çok taciz edilebilirdi ama bu işe yaramaz. Tüm arkadaşlarınızın herkese açık profilini görmek kesinlikle bir gizlilik sorunu olmaz. Eğer arkadaşlık bağlantısının özel olduğunu düşünmüyorsanız (ama yine de neden takdire şayan arkadaşlar söz konusu değilse). Bu, bir yan etki olan gizlilik istismarını kısıtlamak için bir hareket değildi, normal (facebook'a bağlı olmayan) geliştiricilerin facebook verilerini kullanarak işlerini büyütme yeteneğini kapatmak istediler.
Daniel Sharp

3
Facebook son zamanlarda mevcut verilerde büyük değişiklikler yayınladı: bkz. Changelog . taggable_friendsŞimdi hiçbir şey döndürür. Ayrıca, user_friendsizin verilebilmeniz için önce giriş incelemesi gereklidir .
Duncan Jones

Arkadaşlarınızı listeleme gibi temel bir görev yapmanıza izin vermiyorsa bir API sağlamanın anlamı nedir?
6infinity8

17

olmasına rağmen Simon Cross'un cevabı kabul edilip doğru , yapılması gerekenlere bir örnek (Android) ile biraz dayandıracağımı düşündüm. Mümkün olduğu kadar genel tutacağım ve sadece soruya odaklanacağım. Şahsen ben bir veritabanında şeyler depolamak kadar yaralandı böylece yükleme pürüzsüz, ama bu biraz kapsam dışı bir CursorAdapter ve ContentProvider gerektirir.

Buraya kendim geldim ve sonra düşündüm, şimdi ne oldu ?!

Sorun

Tıpkı user3594351 gibi , arkadaş verilerinin boş olduğunu fark ettim. FriendPickerFragment kullanarak bunu öğrendim. Üç ay önce işe yarayan, artık işe yaramıyor. Facebook'un örnekleri bile kırıldı. Yani benim sorunum 'FriendPickerFragment'ı elle nasıl oluşturabilirim?

Ne işe yaramadı

Simon Cross'un 1. Seçeneği , arkadaşlarını uygulamaya davet edecek kadar güçlü değildi. Simon Cross ayrıca İstekler İletişim Kutusunu tavsiye etti, ancak bu bir seferde yalnızca beş isteğe izin verecekti. İstekler iletişim kutusu, oturum açmış herhangi bir Facebook oturumu sırasında aynı arkadaşları da gösterdi. Yararlı değil.

Ne Çalıştı (Özet)

Seçenek # 2 bazı sıkı çalışmalarla. Facebook'un yeni kurallarını yerine getirdiğinizden emin olmalısınız: 1.) Bir oyunsunuz 2.) Bir Canvas uygulamanız var (Web Varlığı) 3.) Uygulamanız Facebook'a kayıtlı. Her şey Ayarlar altındaki Facebook geliştirici web sitesinde yapılır .

Benim app içinde elle arkadaş seçici taklit etmek için aşağıdakileri yaptım:

  1. İki parçayı gösteren bir sekme etkinliği oluşturun. Her parça bir liste gösterir. Bir arkadaşınız ( / ben / arkadaşım ) için bir parça ve davet edilebilir arkadaşlarınız için bir parça ( / ben / invitable_friends) ) için bir parça. Her iki sekmeyi de oluşturmak için aynı parça kodunu kullanın.
  2. Facebook'tan arkadaş verilerini alacak bir AsyncTask oluşturun. Bu veri yüklendikten sonra, değerleri ekrana getirecek olan adaptöre atın.

ayrıntılar

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

Oluşturduğum FacebookFriend sınıfı

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 Facebook JSON: " + e.getLocalizedMessage());
        }
    }
}

20
Oyun dışı uygulamalar için ne dersiniz? Bir arkadaşlık web sitesi ... insanları bulmak için bir oyun, restoranlar bulmak için bir uygulama ... restoranlar bulmak için bir oyun, vb fikir olsun. Peki bu GERÇEKTEN oyunlara yakın mı yoksa bu sizi Facebook'a bir uygulama yerleştirmeye ve reklam platformlarına para harcamaya zorlamanın bir yolu mu? Oyunun ne olduğuna kim karar verecek? Uygulamanızın aslında bir oyun olup olmadığına kim karar verdi? Bu konuda beni yanlış anlamayın, ancak benim için sadece facebook ekosistemini kullanmaya zorlamak istemediğiniz sürece oyun dışı uygulamaları engellemek mantıklı değil.
Mário

@ Mário Bu başlık altında Facebook niyetidir. Gerçekten bir oyun olup olmadığını umursamadıkları için bir şey koyabilir ve bir oyun olarak işaretleyebilirsiniz. Tek umursadıkları cebinden para almak.
sandalone

12

Facebook politikalarını şimdi revize etti. Uygulamanızın bir Canvas uygulaması yoksa ve uygulamanız bir oyun değilse, tüm arkadaş listesini yine de alamazsınız. Tabii ki de taggable_friends var, ama bu sadece etiketleme içindir.

Yalnızca uygulamayı yetkilendiren arkadaşlarınızın listesini çekebileceksiniz.

Graph API 1.0 kullanan uygulamalar 30 Nisan 2015 tarihine kadar çalışacak ve bundan sonra kullanımdan kaldırılacaktır.

Bununla ilgili daha fazla bilgi almak için aşağıdakilere bakın:


3

In Swift 4.2 ve Xcode 10.1:

Arkadaş listesini Facebook'tan almak istiyorsanız, uygulamanızı Facebook'ta incelenmek üzere göndermeniz gerekir. Giriş İzinlerinden bazılarına bakın:

Giriş İzinleri

İşte iki adım:

1) Önce uygulama durumunuz Canlı olmalıdır

2) Facebook'tan gerekli izinleri alın .

1) Uygulama durumumuzu canlı olarak etkinleştirin:

  1. Git uygulamalar sayfasında ve seçmek uygulamanızı

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

  2. Gösterge Tablosu'nun sağ üst köşesinden durumu seçin .

    Resim açıklamasını buraya girin

  3. Gizlilik politikası URL'si gönderin

    Resim açıklamasını buraya girin

  4. Kategori seçin

    Resim açıklamasını buraya girin

  5. Şimdi bizim app Canlı durumda.

    Resim açıklamasını buraya girin

Bir adım tamamlandı.

2) İncelemek için bizim app gönderin:

  1. Önce gerekli istekleri gönderin.

    Örnek: user_friends, user_videos, user_posts vb.

    Resim açıklamasını buraya girin

  2. İkinci olarak, Geçerli İstek sayfasına gidin

    Resim açıklamasını buraya girin

    Örnek: user_events

  3. Tüm ayrıntıları gönder

    Resim açıklamasını buraya girin

  4. Tüm istekler için bu gönderim gibi (user_friends, user_events, user_videos, user_posts, vb.).

  5. Son olarak uygulamanızı incelenmek üzere gönderin.

    İncelemeniz Facebook tarafından kabul edilirse, artık kişileri vs. okumaya hak kazanırsınız.


3
user_friendsİzni çok sınırlıdır. Facebook belgelerinden (Nisan 2019): [Bu yalnızca], söz konusu uygulamayı kullanan arkadaşların listesine erişmek için bir uygulama izni verir. Bu izin sınırlı sayıda iş ortağıyla sınırlıdır ve kullanımı Facebook tarafından önceden onay gerektirir. Bir kişinin başka birinin arkadaş listesinde görünmesi için her iki kişinin de arkadaş listesini uygulamayla paylaşması ve giriş sırasında bu izni devre dışı bırakmamış olması gerekir.
dearsina

2

Simon'un belirttiği gibi, bu yeni Facebook API'sinde mümkün değildir. Saf teknik olarak konuşursanız , tarayıcı otomasyonu ile yapabilirsiniz.

  • bu Facebook politikasına aykırıdır, bu yüzden yaşadığınız ülkeye bağlı olarak bu yasal olmayabilir
  • kimlik bilgilerinizi kullanmanız / kullanıcıdan kimlik bilgilerini istemeniz ve muhtemelen depolamanız gerekir (simetrik olarak şifrelenmiş olsa bile şifreleri saklamak iyi bir fikir değildir)
  • Facebook API'larını değiştirdiğinde, tarayıcı otomasyon kodunu da güncellemeniz gerekir (uygulamanızın güncellemelerini zorlayamazsanız, tarayıcı otomasyon parçasını bir web hizmeti olarak koymalısınız)
  • bu OAuth kavramını atlıyor
  • Öte yandan, duygularımın arkadaşlarımın listesi de dahil olmak üzere verilerime sahip olduğum ve Facebook'un API aracılığıyla bunlara erişmemi kısıtlamaması gerekiyor

WatiN kullanarak örnek uygulama :

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

Bu yaklaşımın uygulanmasını sağlayan prototip (C # / WatiN kullanarak) bkz. Https://github.com/svejdo1/ShadowApi . Ayrıca, kişilerinizin bir listesini alan Facebook bağlayıcısının dinamik güncellemesine de izin verir.


2
Kodunuz, uygulamanın kullanıcının kullanıcı adı ve şifresine erişimi olduğunu varsayar. OAuth bu şekilde çalışmaz ve çoğu kullanıcı FB kullanıcı adını ve şifresini bir uygulamaya sağlamaz. Bu büyük bir güvenlik riski olacaktır.
jbustamovej

32
Bu Facebook politikasına aykırıdır. Bu tavsiyeye uyulmamalıdır.
Simon Cross

3
Başka bir notta, kullanıcılarınızın kesmek için kimlik bilgilerinizi korumanız bile güvenli değildir. Birisinin kodunuzu kullanmaya karar vermesi durumunda, lütfen uri'yi https olarak değiştirerek SSL kullandığından emin olun.
Rogala

8
Artı yüzünü itmek için bir tane!
Skynet

12
Hepiniz Facebook politikaları bir tür Uluslararası Hukuk gibi geliyor ve onu çiğneyerek bir suçlusunuz. Ayrıca Facebook'un sadece akılda kalan kullanıcı için en iyisine sahip olduğunu düşünüyorsunuz, bu da @OndrejSvejdar'ın belirttiği gibi yanlış olduğunu düşünüyorum, çünkü o zaman sadece diğer uygulamalarda görünmek istiyorsanız seçmenize izin vereceklerdi. Bence bu, Facebook'un ÜCRETSİZ olarak kendi platformları aracılığıyla başkalarının büyümesini bozmak için bir hamle. Bunun yerine insanlar uygulamalarını, hizmetlerini, oyunlarını, haberlerini vb. Doğrudan Facebook'ta geliştirmeye başlamalıdır. Ve olmazsa Facebook reklamları için ödeme yapın.
JustGoscha

2

/me/taggable_friends?limit=5000JavaScript kodunuzu kullanmayı deneyin

Veya

Grafik API'sını deneyin :

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


2
Düşündüğüm gibi - buradaki aşağı oylar, "Bu son noktanın kullanımı Facebook tarafından incelenmeyi gerektirir ve yalnızca kullanıcının bir gönderide etiketlemesine izin vermek için bir arkadaş listesi oluşturduğunuz durumda kullanılmalıdır." Bunun hakkında daha fazla bilgiyi seçilen cevapta okuyabilirsiniz.
moonvader

{"data": [], "özet": {"total_count": 414}} Bu json veri bloğunu null arkadaş alamadım. Ne yapabilirim?
Makvin

-1

Facebook SDK Graph API v2.0 veya üzeri sürümlerde , user_friends artık her girişte varsayılan olarak bulunmadığından , Facebook girişi sırasında her kullanıcının user_friends iznini istemelisiniz ; bunu eklemeliyiz.

Her kullanıcının / me / friends yanıtında görünmesi için user_friends'a izin vermesi gerekir .

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

Yani Facebook girişi sırasında, tüm izinleri içeren bir ekran ister:

Resim açıklamasını buraya girin

Kullanıcı Devam düğmesine basarsa , izinler ayarlanır. Grafik API'sını kullanarak arkadaş listesine eriştiğinizde, yukarıdaki gibi uygulamaya giriş yapan arkadaşlarınız listelenir

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

            print(result!)
        }
    })
}

Çıktı, Facebook aracılığıyla uygulamanıza giriş sırasında user_friends izni veren kullanıcıları içerecektir .

{
    data = (
             {
                 id = xxxxxxxxxx;
                 name = "xxxxxxxx";
             }
           );
    paging = {
        cursors = {
            after = xxxxxx;
            before = xxxxxxx;
        };
    };
    summary = {
        "total_count" = 8;
    };
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.