More Facebook Application Gotchas
This is a continuation of my previous article, 5 Facebook Application Gotchas.
-
User invites
Everyone loves user invites. Well, every application developer, at least. Requests are achieved by calling $facebook->api_client->notifications_sendRequest(...). Facebook only allows you to send notifications to ten users at a time, however.
To implement an invite page create a URL called, say, http://apps.facebook.com/myapp/process. You have a form which lets users select their friends who haven't installed the app, as follows
global $facebook; $fql = "SELECT uid, strlen(books) FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = {$facebook->user}) AND has_added_app = 0"; $uids = $facebook->api_client->fql_query($fql); // Render the form using the above UIDS
Have the form you render submit to /process, which should behave roughly as follows
global $facebook; if (isset($request['uids'])) { if (empty($request['uids'])) $facebook->redirect('APP URL'); $array = explode(',', $request['uids']); } elseif (isset($request['users'])) { $array = array_keys($request['users']); } else { $facebook->redirect('APP URL'); } $uids = array(); while (count($array) > 0 and count($uids) < 10) { $uids[] = array_shift($array); } $url = $facebook->api_client->sendRequest($uids, 'MyApp', $msg, $img_url, true); if ($url) { $facebook->redirect($url . "&canvas=1&next=" . urlencode("process?uids=" . implode(',', $array))); } else { $facebook->redirect('APP URL'); }
Note, the next parameter tells the request URL where to redirect after a batch has been processed. If it is a canvas page you should include canvas=1.
-
CSS ids
Facebook only allows inline styles and styles within style tags. To prevent you from affecting the layout of the rest of Facebook it inserts a wrapper div around your content and assigns it an id of the form app_XXXX, where XXXX is your application ID number. It then affixes #app_XXXX to all your CSS rules.
This means that, for example, CSS hacks which involve things like html > * won't work since they will come out as #app_XXXX html > * on the other side. For ID rules, however, it does something much more annoying: it rewrites the ID itself. So, e.g., a rule like #MyDiv h1 becomes #app_XXXX_MyDiv h1 rather than #app_XXXX #MyDiv h1. There's no good reason for this, AFAIK, but it means using IDs on a page inside Facebook becomes tedious — you need to know your application ID number.
To work around this I just uses classes when writing Facebook pages.
-
Facebook is Strict
In order to strip out bad elements and alter the CSS Facebook actually lexes and parses your code. And it is strict. Like, really strict — much more strict than any browser.
If you're the developer you can see the error messages and I advise you to clean them up. With CSS at least bad elements just get dropped. I'd also bet money than acceptance into the application directory is contingent on you outputting well-formed FBML.
-
Use an Icon
The process for what applications get accepted and what applications get rejected from the application directory is totally opaque. The best we have is that an application must "work," have at least five users, have an icon, and follow the TOS.
Looking over the application directory you see plenty of apps with terrible icons, so the quality doesn't so much matter as presence does. Just create one and upload it before you submit your application to the directory. You can change it later if you want, but you won't get accepted without one.
-
No conditional comments
The Facebook JavaScript doesn't always play nice with IE. That is, you can find permutations which work in Safari and Firefox but fail in IE. Shucks. Unfortunately Facebook doesn't allow conditional comments which would give you the ability to let your application degrade nicely in IE.
What's more, because of the way Facebook rewrites CSS, most of the CSS hacks don't work. Facebook does, however, pass along the user agent when it requests data from your server, so if you must absolutely have browser-specific code you'll have to push the logic back into the PHP (or Java, if you swing that way).
I had a sixth gotcha but I forgot what it was. Oops!