Hi, I'm Adam. Email me about: CTOs, Mobile/iOS, Project Management, and Development

Ten tips and tricks for writing Facebook Apps

(Only a couple of these are java-specific, but this is a.k.a.: “How to make Facebook Apps using Java – part 3”)

(I assume you’ve already had a look at part 1 and part 2? They’re more beginner-oriented)

Bugs, Misconceptions, and Subtle Features

Interfacing with Facebook’s servers is pretty hard, considering how seemingly trivial the interface is. Obviously the almost total lack of documentation is mostly to blame for this, but some of it is just common bugs that have yet to be fixed.

So, here’s ten things I’ve found whilst fiddling with the API, and some of the nicer features that may not be immediately obvious even if you do read the docs provided by FB (you should go read all of them, but … there’s some bad organization and layout, so it can be a chore reading the mega-long HTML pages, with many of the API features having just blanks for description fields :( ).

#1 – FacebookRestClient.java is broken (bug)

I’ve had a couple of problems with this class, provided by FB themselves, although most of them turned out to be just inconveniences / bad design. This one, however, is clearly a bug, since it’s impossible to use some of the methods in the class until you fix their source code.

NOTE: I’ve done this for you, at the bottom of this page is a link to download a “fixed” version of the source, along with some other useful files. What follows is FYI in case you want to make the change yourself…

In line 103, you need to change:


protected class Pair<N, V> {

to:


public class Pair<N, V> {

Note: without this, you cannot legally create instances of that class from within your own code.

If you cannot create instances of that class, you cannot provide the arguments to the handful of methods that REQUIRE a Pair<N,v> (or a list of them) as one of their arugments.

I’m not sure why the author of the class made this class protected – seems to just be a silly mistake. I imagine they thought that perhaps “it’s an internal hidden class – therefore I must hide it” … but it seems to exist mainly to be one of the REQUIRED arguments to the public methods, so this is obviously wrong. Oh well.

#2 – Callback URL is not a page, it’s a directory

This one is annoyingly subtle – everywhere you use the callback URL, and create canvas pages, this isn’t explained. When you are REQUIRED to invent a URL for this, you’re not told what it really is. Instead you have to dig into the docs to find the following nugget:

If you want to create Facebook Canvas pages, you must specify a directory name for your pages. Directory names are unique so you cannot have a name another app has claimed. Once you specify a directory name, going to http://apps.facebook.com/YOUR_DIRECTORY_NAME/pagex.abc will render pagex.abc from pagex.abc in the Facebook Canvas.

Note: that is CORRECT even though it appears to have a typo – Facebook really does render the page pagex.abc with no slash inserted between the two parts – if you don’t put a slash on the end of your Callback URL when you type it into the Create Application form, you’ll find there’s no slash between the Callback URL and the “pagex.abc”.

Note2: You can, in fact, deliberately request “http://apps.facebook.com/YOUR_DIRECTORY_NAME//pagex.abc” (note the double-slash) to cause FB to insert a slash in the request it sends to your webserver. But I woudl advise against this – it’s the kind of behaviour that’s likely to be removed in the future, since double-slashes are not legal in URL’s IIRC (c.f. the URL/URI RFC’s if you’re interested…), and are usually a sign of attempts to hack a server (so are strongly discouraged).

I’d actually given up on creating canvas pages, and had just moved to doing everything with relative iframe links. This is, apparently, WRONG (and probably explains some of the other inconveniences I’ve had to date).

So, to be entirely clear, here’s the way you should make your Canvas pages (I think!)

  1. When you choose a Callback URL, make sure you type it in with a slash on the end
  2. Each page you want as part of your app you should link to as “[callback URL]/[page name]”
  3. In J2EE, map a servlet (in the simplest case; get more fancy if you prefer using struts etc) onto the directory path
  4. Configure that servlet to handle authentication (see my previous post on how to do facebook authentication)
  5. …and to chain the request to a different servlet by reading the “[page name]” part of the incoming URL

NB: there are various ways of doing that more elegantly in J2EE. I don’t want to start writing a tutorial on J2EE, so I’m not going to go into them – there’s tonnes and tonnes of info and docs on this stuff if you don’t know it yet … google is your friend!

#3 – Facebook apps can ONLY change things when one of their users is in the middle of using Facebook

You CANNOT perform actions with the FB API unless at least one of your app’s users is actively logged in to Facebook AND is using your application.

This is by design, but it has some nasty knock-on effects. Essentially, it seriously limits your ability to interface FB with other applications and networks, because although FB users can have arbitrary effects on external data, external data is forcibly prevented from having any effect on FB.

Example? Well, you can only post to the newsfeed of user X if user X themself is currently using FB *right now* at the moment you want to do the post. That means that you cannot, say, post to someone’s newsfeed (and by extension to all their Friends’ feeds for free) each time “someone visits my MySpace page” or each time “someone rates me a 10 on HotOrNot”.

There are workarounds:

Workaround 1: many of the API actions can legally be peformed for ANY of the “users of your application” if “any” of the other users are actively logged-in. For instance, you can query the friends of one of your users so long as at least one user is logged-in. Assuming your app is popular, there will always be SOMEONE logged-in, and you can piggyback of that logged-in user to refresh other data inside your app that depends upon reading info from facebook.

Workaround 2: In particular, anywhere that you use FBML, you can insert an tag, and for a given fb:ref it is possible – with a single method call – to simultaneously update ALL Facebook pages (every user profile, for instance) that has the fb:ref tag in it.

The way the tag works is that you include something like this:


<fb:ref url="http://yoursite/facebook/profile-FBML" />

inside the FBML you “set” as each user’s profile-FBML for your app.

Sometime later, perhaps once every hour – and only when you have a logged-in user who’s Facebook authToken you’re using! – you call:


// See item #10 on this page for more info!
iFacebookClient.fbml_refreshRefUrl( "http://yoursite/facebook/profile-FBML" )

…and ALL the user profiles will update simultaneously. Allegedly – I haven’t tried this yet myself, I’m only using FBML a very small amount at the moment. I’ll update this as and when I have problems / find solutions / etc :).

NB: this ONLY allows you to update the “common” or shared parts of people’s profiles (or whatever FBML you’re setting) – it doesn’t allow you to update customized FBML for each person.

i.e. you could use it to have a “top 10 leaderboard of all users” that appers in everyone’s profile and updates frequently seemingly automatically, but you could NOT use it to have a “your position on the leaderboard” that updates automatically (you would only be able to update that part for each user when that particular user simultaneously logged-in to your app and to facebook).

However … you can still use workaround #1 to update EVERYONE’s profiles manually, one-by-one, whenever ANYONE is logged-in, because the method call to update an individual profile has an optional argument that lets you specify exactly which profile to update – it doesn’t HAVE to update only the profile of the logged-in user.

#4 – Javascript is not allowed in FBML

Currently, Javascript is not allowed. If you include attributes like onClick, onMouseOver, onKeyUp, etc. we will strip them out.

So, in case you were wondering, *that’s* why your javascript ain’t working…

#5 – CSS is not allowed in FBML (with exceptions)

Referencing external CSS stylesheets is not allowed, but you can use style tags and put your CSS definitions there.

I *think* that’s another typo (argh!) – I think they meant “but you can use style ATTRIBUTES” (i.e. the person writing it didn’t realise that style=”” is an HTML attribute, whereas HTML tags look like this: <span></span>).

i.e. you are NOT allowed to do this:


<head>
< ... stylesheet href="...">

(you’re pointing to the stylesheet on some other website (even your own website) on the internet, using the URL of the stylesheet to tell HTML to pull it in)

…but you ARE allowed to do this:


<span style="border-top: 30px; margin-right: 0; text: #ff0000;">
some formatted text
</span>

So, you’re allowed to “use” CSS within the HTML, but you just aren’t allowed to make your HTML clean, readable, easy to edit, or easy to debug. That sucks. Most people who use CSS will avoid doing “CSS in style attributes” like the plague – it’s messy and horrible and really hard to maintain.

But at least you can actually use CSS, instead of being forced to write 10-years-old HTML from the pre-CSS days.

#6 – The Create-App HTML form (bug)

The create-app page on FB is broken – it periodically saves its data to the live servers, but the data it displays that it THINKS it has saved is not the same as what has ACTUALLY been saved. If you change e.g. your Callback URL, it will APPEAR to change on the settings, but it won’t have changed in real life, but then if you refresh the settings it will APPEAR to have reverted to the old value, but if you “edit” it using the link provided, the value in the textbox will be the NEW value (that it has just claimed it is NOT using).
This is very confusing, and a silly bug, but what it means is: when you change your callback URL, just keep trying refresh on your canvas page URL (apps.fb.com/yourapp) until it finally “works”. Some people have had to wait hours for this to happen, others waited minutes. I found it took around an hour to update.

Also … that whole page is a nightmare. It’s badly explained, it has far too much text, and critically important concepts (like your Callback URL, which is almost the only thing on the whole page you have to fill out, but which – contrary to the instructions! – you HAVE to fill out) are buried deep within it. c.f. Item number 2 above for more info just on the Callback URL alone, info which SHOULD have been embedded in this form.

#7 – Fancy GUI hide/show effects for free

Adding the attributes clicktohide and clicktoshow, you can dynamically hide and show content rendered with FBML

FB even give an example (how nice of them):


<span id="cdc03" style="background: yellow">this can appear and disappear</span>
<input type="submit" clicktohide="cdc03" value="hide"/>
<input type="submit" clicktoshow="cdc03" value="show"/>

#8, #9, and #10 – FacebookRestClient.java is very bad java (bug)

Actually, I got fed up with this crappy class. Problems include:

  1. It’s not an interface
  2. It’s got bugs (c.f. the Pair inner class bug above)
  3. Many methods are 100% undocumented
  4. The class itself is 100% undocumented
  5. Some of the undocumented methods have undocumented REQUIRED ways to call them

So … I took their source code and refactored it.

  1. Get the new interface here (compile all your code against the interface – anything less is just Bad Java Coding)
  2. Get the new “main implementation” here (this is almost 100% the original official FB source code, just refactored a little to fix some nasty design flaws in their use of conflicting method signatures)
  3. Get the new “Pair” class here (used to be contained within the old class with incorrect signature (see the bug above about this), now refactored into separate source file)

Epilogue…

I hope these prove useful to you. If you have any problems, or want more tips on using Facebook, feel free to leave a comment. This is the third post I’ve done on how to write facebook apps, and I’ve got at least one more I want to do yet. If you want to keep up to date with these, add the “facebook” category on this blog to your RSS reader (see also part 1 and part 2)…


16 thoughts on “Ten tips and tricks for writing Facebook Apps”

Comments are closed.