Recursive Facebook API Call - facebook

Basically this is what I want to do
- Get all my likes (page likes)
- Get all my friends
- for each of my friends, get their likes
- for each of their likes, do something
Now, the way I'm doing this is by using JS SDK, because I've tried PHP SDK and it's really slow (so slow that PHP error of maximum execution time kicks in), is PHP SDK always slower than JS? My script is something like this :
var newArray = [];
FB.api('me/likes', function(response){
FB.api('me/friends', function(friends){
$(friends).each(function(){
FB.api(this.uid+'/likes', function(fr_likes){
$(fr_likes).each(function(){
//save this friend likes to newArray
newArray.push(this);
});
});
});
});
});
//call newArray outside FB scope doesn't work at first
console.log(newArray); //returns [] / empty
But if I use chrome console to call newArray after awhile, newArray is slowly populated with FB data.
So my question is :
Can I wait for all the FB.api calls to be complete before doing something outside FB scope?
What is the best practice for doing something like that (recursive FB api calls)?
Thanks for the answer

You should read up on the Batch API. It allows you to make multiple requests in one single round-trip to Facebook's servers. Should speed things up considerably.

Related

Why does my facebook friendlist request doesn't show as many friends as on my profile?

I'm trying to get my users friends lists by using the facebook graph API doing so:
FB.api('me/friends', function(response) {
console.log(response);
user.friends = response;
});
When I test on my own profile I get 95% of my fb friends (583 friends instead of the 602 I can see on my profile). Thus, I see in the response object there is a "next" url for the pagination function which doesn't return anything when triggered. Why is this happening ? Where does that possibly come from ?
Thanks
If you have a problem with next URL for the pagination, try using the offset and limit parameters in the URI.
For example, instead of making an API call to me/friends, make a call to me/friends?limit=100&offset=0. This will start the list of your friends from an offset of 0 and will display a list of 100 friends on on each page. The next URL will work just fine in this case. You can however increase the limit of the users per page.

Facebook app - permissions varying from tester to tester

Bit of an odd one: I've created an app that uses a jQuery AJAX request to query the Graph API and access a list of a given user's Likes (someone on my Friends list). I can use this within my app, and I get the same result as if I'd run the query through the Developer tools Graph API Explorer site (https://developers.facebook.com/tools/explorer).
The fun begins when people on the Testers list for the app (which is sandboxed) perform exactly the same actions, with the same friend (who isn't on the testers list); they don't receive any data back from the Graph API at all.
The testers have granted my app all the same permissions as I have, so why would we be getting different results?
Finally - I think I've found the solution.
By switching the Facebook JavaScript SDK file to a direct link rather than an asynchronous download, and calling the FB.login function with extra permissions defined in the scope later down the page:
FB.login(function (response) {
if (response.authResponse) {
// init app here
} else {
// cancelled
}
}, { scope: 'user_likes,friends_likes' });
... the testers are able to access their friends' Likes. Phew!

Facebook graph API 'friends' request now only returning 25 friends per page? What's going on?

My application(game) has been running on Facebook for some time. I start by requesting a friends list via the graph API call: my-uid/friends
asking for user name and profile pic.
Normally I get back a list of all my friends up to a few thousand, until it starts putting friends on to the next page. Which is nice as most of my users get friends in 1 call.
Suddenly however, and with no changes to the app. about 40 minutes ago (18:40 Tuesday (PDT) - 2nd May 2012) I started getting responses with only 25 friends per 'page'!
I can still get my whole friends list using multiple calls, but the game is not currently set up to do that properly. Can anyone tell me why the sudden change? Anyone else seen similar problems and how do I get the list to give me up to 5000 friends per page like it used to.
Reproducible using the Graph API Explorer
I don't know what else to tell you; perhaps the default number returned has changed, but when I try, a call to /me/friends?limit=5000 returns the full list for me (but my friends list is >500 and < 1000 , so maybe it cuts off somewhere along the way)
(Side note: the average number of friends has been found to be ~190 so presumably most users will have less than 500 anyway, and having to page above 500 would be an edge case
In SDK 4.7 you need to pass in a bundle with the number of friends you want to return, I have set it to 5000 as this is the maximum number of friends you can have on Facebook.
You also need to set up your app as a game in the facebook dev console and use invitable friends to get a full friends list
Create your bundle
Bundle bundle = new Bundle();
Add params to your bundle
bundle.putInt("limit", 5000);
Then pass it in to your GraphRequest
new GraphRequest(
AccessToken.getCurrentAccessToken(),
"/me/invitable_friends",
bundle,
HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
//Do something with the response
}
}
).executeAsync();
It seems that facebook changed its limit to 25 results in other api calls too (feed, posts, friends, etc), if you request friends without parameters the JSON response shows the following:
"paging": {
"next": "https://graph.facebook.com/USER_ID/friends?format=json&limit=25&offset=25&__after_id=LAST_ID"
}
Anyway you could/should always set limit & offset parameters to prevent this kind of things, limit = 0 will return all your friends list.
https://graph.facebook.com/USER_ID/friends?limit=0
If you are only requesting friends from a normal user the maximum number allowed is 5,000 so the limit should could be either 0 or 5,000 if you are requesting info from a facebook page or other kind of api calls like posts or feed this limit could increase or decrease.
(Update) Facebook fixed this bug so setting limit to 0 returns 0 friends, you should set a positive limit, thanks Dinuz
I think the best thing you can do is to add limit=5000 parameter as Igy says.
However I posted a bug report since this change wasn't noticed or described in the document.
The number of results returned from the /v2.2/me/friends endpoint now defaults to 25.
Friend list now only returns friends who also use your app: The list of friends returned via the /me/friends endpoint is now limited to the list of friends that have authorized your app.
See Facebook changes
Facebook API change log
If you are using GraphRequest() (e.g. in React Native), you can put it directly in the string field, like so :
new GraphRequest(
'/me',
{
accessToken,
parameters: {
fields: {
string: 'id,email,first_name,last_name,friends.limit(5000)'
}
}
...

Is it possible to do non-blocking Facebook API calls, using node.js?

I want to use node.js to boost my Facebook applications performance. Imagine application that tries to compute who is you best friend on Facebook, fetching a lot of data from API calls - determining how many times your friends have posted to your wall, how many photos you have marked on together - so on.
So instead of running that calls one after one, as I do using PHP I have an idea to send them all together to Facebook using non-blocking, asynchronous nature of Node.js.
So overall execution time will be the time of most time consuming API call, but not the sum of execution time of the every call, right?
I try to use node-facebook-sdk (https://github.com/tenorviol/node-facebook-sdk) to make Facebook API calls and it seems to be that it's blocking, isn't it?
Just quick and dirty modification of example code, requesting 3 user profiles, seems that calls are not asynchronous, each sending to Facebook after previous has completed. Are there any way to avoid that?
Thank in advance!
var fbsdk = require('facebook-sdk');
var facebook = new fbsdk.Facebook({
appId : '_APPID_',
secret : '_SECRET_'
});
var i = 0;
setInterval(function() {
i++;
console.log("TICK " + i);
}, 500);
facebook.api('/100000997949108', function(data) {
console.log(data);
});
facebook.api('/1609464095', function(data) {
console.log(data);
});
facebook.api('/100000560820400', function(data) {
console.log(data);
});
This library will help you out with all things async. I hashed the particular method you would want to use for your problem, but the library as a whole is excellent at abstracting some of the more tedious (and ugly!) async patterns away. Great transitioning tool for those coming from procedural and you can take a peak under the covers if you want to learn some async patterns.
https://github.com/caolan/async/#parallel

Set up facebook UrchinTracker for aJax calls for Google Analytics

I have set up the Google Analytics in my FBML facebook application. It works for tracking the php pages. (I can see the report in GA).
However, I also want to track the aJax calls, because most of the pages of my application is ajax driven, rather than loading differnet php pages.
so, that's what I put in the code (before ajax call)
Facebook.urchinTracker('/importantpage/');
THere is no error return when running the application.
However, when I look at the Google Analytics, I can't find any report showing this is being tracked. I look at the Event tracking.. nothing. I look at the overview, it only shows the php pages statistic.
So, where should I look in Google Analytics? and do I need to set up anything in GA for tracking the ajax call for 'importantpage' ?
try calling urchin within you AJAX function. Like :
function callPage(div,params, page)
{
Facebook.urchinTracker(page);
var ajax_content = new Ajax();
ajax_content.responseType = Ajax.FBML;
ajax_content.ondone = function(data)
{
document.getElementById(div).setInnerFBML(data);
}
var params={"Params":params,"target":div};
ajax_content.post(page,params);
}