Sunday, June 7, 2009

Facebook Connect: Avoid race conditions with FB.ensureInit

I've been playing with Facebook Connect for a while now. Actually, the JavaScript client library is such a relief. It enables the API consumer to distribute the overhead of Facebook API calls on all the clients, hence dramatically boost the application performance.

However, IMHO, there is a single major issue with The Facebook JavaScript client library. To make it clear, let's take a quick look on the typical steps to use the library. There are two main steps:

1. initializing the library


var fbApiKey = "your_api_key_here";
FB.init(fbApiKey, "/xd_receiver.htm");


2. Making the desired API call

var fbClient = new FB.ApiClient(fbApiKey);
fbClient.users_getInfo(fbUserId, ['name', 'hometown_location', 'birthday'], showUserInfo);


The exact previous code snippet seems okay. Actually, it runs perfect in most cases. However, the previous code snippet would 'sometimes' cause an error and wouldn't run. What kills me is that the error is not clear: "Can't get base domain property when api key is not set" !!

After digging it up for a while, I found out the cause of the 'inconsistent' problem. The initialization call "FB.init" is asynchronous. The initialization process starts and the code continues on running. The error occurs in the cases where the API call happens to run before the asynchronous call is done (i.e. FB is not fully initialized). As confusing as the problem could get, the solution was pretty simple; instead of making the API call directly, attach your call to the callback of the great "FB.ensureInit" function:

FB.ensureInit(function(){
var fbClient = new FB.ApiClient(fbApiKey);
fbClient.users_getInfo(fbUserId, ['name', 'hometown_location', 'birthday'], showUserInfo);
});


What really drives me crazy is that, the API calls that requires complete initialization are known. Why wouldn't the library internally handle this burden ??!! Why wouldn't the implementation of all those call internally block until FB is fully initialized ??!! That's a question whose answer I would really like to know someday.