flogiston

Blog

My Facebook Connect experience

· admin · Dev, Java

For one of our customers, we needed to integrate with Facebook.  For signing in, for  publishing feeds, for adding profile boxes, the works.

Facebook has a lot of documentation available, so this would be fairly easy. I thought.

The initial setup was a php app.  A short demo was build by one of my colleagues.  However, due to several restrictions, the app had to be build in java.  After a short look around, we decided to go with the java api hosted on google code (http://code.google.com/p/facebook-java-api/)

We have a local environment, a shared development environment, an internal staging environment, a pre-production staging that mimics the rather complex production environment and the production environment with 20 domains (localized content).

So, step one was to create a test application on Facebook using one of our development accounts. The first thing that bugged me was that I couldn't create a simple app using the "localhost" domain while my colleague had defined several of them.   So I decided to go with the ip (127.0.0.1).  It took a while to figure out the part with the callback since our application wasn't running in the root context and it's function wasn't really clear.

Once I had the app defined and a callback controller (we're using Spring) I was ready to retrieve the user data.  I thought. But while trying to get the callback part working, I think I messed up the Facebook application configuration.  Nothing seemed to work.  I didn't get the login form.  Or I got it and it closed immediately.

So, I deleted the test app, created a new one.  Reconfigured the appkey and the secret key.  And now I could log in.  Using the facebook-java-api it was fairly easy to retrieve the user data and a list of his friends.

Invite a friend functionality was added and tested. It worked fine using dummy data. So now the research was done.  Everything seemed to be fairly easy.

So now it was time to define a production-ready app and start working.  A co-worker created the 25+ apps in facebook and I started on posting a feed entry to the user.

According to the documentation, you first have to "register" a template of the feed you wish to post.  This can be done manually using their web interface or programmatically.  Since we don't know which user will be on which domain and in which language, we had to register a template in all 20 languages in all 25+ domains.  So a wrote a little run-once tool for this.

We stored the template id's in the database and performed a lookup based on the domain and locale.  And here's where I created for myself yet another hurdle.  For some reason not even known to myself, I configured the run-once tool so it connected to the shared development database instead of my personal development database on the same server.  So the bundle id, though valid and existing, did not belong to the FB application key on my localhost server.  Had I done the look-up based on the app-key I would have noticed this immediately.  However, due to the (very) late hours I presume, I didn't notice it at all.  As a result, I got some very, very odd behavior:

When I clicked the button to post the feed, the pop-up window would open to log in into Facebook.  When I provided my credentials, the window would close.  Each time.  No error message, no warning.  Just gone.  When I viewed the source, I saw an application id and a bundle id.

It was crazy.  The exact same code worked when I did my research.  What was I doing wrong?  Only after tedious hours I detected my mistake.  So I deleted all bundle ids and re-registered the templates on my own database, cleared all my cookies and tried again.

Bingo!

When the template bundle id doesn't exist, you get a nice message from Facebook.  But when you use an existing bundle id from a different application, you get a window that doesn't open or only opens shortly.

Ok, now that was done.  Only one thing was left to do: set a profile box.  The documentation was clear: first call the profile_setFBML on the server side so there is content and then just use the FB-tag <fb:add-section-button section="profile" />

Nothing to it.

Or so I thought.

Unfortunately, there are several method calls in the facebook-java-api to setFBML.  It took quite a while to figure out the correct one: profile_setFBML(facebookId, profileboxcontent, null, null, profileboxmaincontent);

But when I went to Facebook, I STILL couldn't see the content I send out.  And still no button.

So back to  google.  I came across  this post: http://forum.developers.facebook.com/viewtopic.php?id=23674

Mmm, let's try it out.

String fbHandleNameWide = "box_wide_" + facebookId;
String fbHandleNameNarrow = "box_narrow_" + facebookId;
fbclient.fbml_setRefHandle(fbHandleNameWide, boxcontent);
fbclient.fbml_setRefHandle(fbHandleNameNarrow + facebookId, boxcontent);
String wideHandle = "<fb:ref handle=\"" + fbHandleNameWide + "\" />";
String narrowHandle = "<fb:ref handle=\"" + fbHandleNameNarrow + "\" />";
String profile = "<fb:wide>" + wideHandle + "</fb:wide><fb:narrow>" + narrowHandle + "</fb:narrow>";
String profile_main = narrowHandle;
return fbclient.profile_setFBML(facebookId, profile, null, null, profile_main);

I created a reference first as defined in that post and then used that reference in the profile_setFBML.  FINALLY, I could see the content  when I went to facebook.  But still no button.

I tried many, many different things.  But nothing, nothing at all, worked.  I had the namespace xmlns:fb defined, I had a valid FB application key, I had "XFBML" in the init function, I had the <fb:add-section-button thingy.  I am a very, very patient person.  But this was buggin' me way too long.

The co-worker who set up the demo came by a few times to help me out.  But we couldn't see anything wrong.

Finally I found another forum post from a person who used javascript to show the button:http://forum.developers.facebook.com/viewtopic.php?id=23009

<script src="http://static.new.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>
<script type="text/javascript">
FB_RequireFeatures(["XFBML"],
FB.Facebook.init('<api_key>', '<path to receiver.html>, null);
</script> <div id="profileAddDiv" >&nbsp;</div>
<script type="text/javascript">
FB.Connect.showAddSectionButton('profile',document.getElementById('profileAddDiv'));
</script>

Now it would work.  I was pretty sure of it.  N O T !

My co-worker dropped by again.  Since we now had a javascript way of doing it, I fired up firebug and checked out the response.

The request was invalid: Invalid URL, Request to long, or a few other things.

My server was running on 127.0.0.1:8080 as is often the case when running your tomcat in stand alone mode.

Half jokingly, my co-worker said: maybe Facebook has difficulties with the double point ":".   Yeah, right!

But just to be on the safe side, I deployed all my changes to our shared development environment.  That has an apache in front of the tomcats so it's run on the default port.  After cruisecontrol had build the codebase, I pointed my browser to the development environment.  LO AND BEHOLD....

The button appeared magically.

FACEBOOK DOESN'T LIKE JAVA!!!

For the first time in my career I cursed.

But at least it worked.  I tied up the loose ends, documented my findings on our internal wiki and went home.  Partially relieved because the Facebook integration is finally completed.  Partially frustrated because I lost valuable time on things that shouldn't be so complicated.

Anyway.  Another lesson learned.

4 comments

biplav ·

the prob might be that in the call back url u might have forgot to include the port address.. on the facebook my app page.

admin ·

Hi biplav, I did include the port in the callback url. Otherwise I wouln't be able to sign in, post a feed or lauch the invite a friend window. It seems that only the add section button considers the ":" as an invalid part of the url.

Background Checks ·

Interestingly I to had few problems of my own with facebook connect. But one of my friends was able to help me out with it. I'll post a URL with the solution if you want. Cheers

admin ·

Hi,

please do! I found connecting with facebook using java not that easy so any extra info is surely appreciated.

Kind regards,
-Flogiston