Recently I had the opportunity to take an Adobe AIR application, nomee.com, and integrate a portion of it into Facebook. In this article I'm going to cover some of the things that I learned along the way while I was trying to understand exactly what I could and couldn't do inside of Facebook.

Figure 1. The Nomee application
First I'll start with an overview of the different places
you can put flash on the Facebook site, followed by an overview of the
different ways to launch Flash in the Facebook Platform. Then I will talk about flashvars in the world of Facebook. I'll end with a quick overview of what you can't do
with flash on Facebook.
Facebook has a number of integration points throughout the site. These are covered in more detail in the Facebook developer wiki page. The main points of integration are the Canvas page, Application tab, Boxes tab, or Wall.
Important: Except on your canvas page, Facebook restricts how Flash can run. Before any Flash can run on the Application or Boxes tabs or wall, the user has to click the placeholder to activate the Flash movie. This is a lot like how YouTube places the big play button on top of their videos. Facebook does this so that developers don't fill up Facebook pages with lots of animated noise making applications running at the same time on a page. Because Flash can do so much, users need to start the applications.
Luckily, Facebook gives you the ability to create your own
placeholder graphic that can tell users to click on the graphic to start the
flash movie. This is set with the <fb:swf imgsrc=""> attribute.
Every application is given a unique application URL by Facebook when you register your application in the developer section. This URL starts with http://apps.facebook.com/ and is followed by a unique name of your choosing. Facebook will proxy requests to this domain to your real web server so users will never need to know the URL to your server. It also allows you to change your servers as needed without breaking Facebook bookmarks.
For instance, if you are requesting http://apps.facebook.com/<your app name>/usersInfo.htm, Facebook (behind the scenes) will request userInfo.htm from your server and return it to the user on Facebook. By doing it this way, you are able to run Facebook Markup Language (FBML) on your pages even if the application is hosted in an IFrame.
The main application page has the least amount of restrictions on it. You can use URL parameters, you can run your own ads, and Facebook doesn't sanitize the JavaScript you want to run.
the JavaScript you'd like to run is not sterilized, for lack of a better word (see below for more details).
You are given two choices when setting up your Facebook application. You can run it as straight FBML or as an IFrame inside of the Facebook page. When you run it as FBML you will get to take see some benefits from Facebook caching of the FBML page; however, you will also be slightly limited on what you can do. Specifically, you won't be able to pass URL parameters into your pages.
With the Nomee application, our plan was to redirect a large portion of the traffic back to our application page for two reasons: having the ability to run ads and, more importantly, we needed a guaranteed way to view a user's Nomee card. When users embed their cards on Facebook, from our AIR client, we have no guarantees that they may actually add our application to their profile pages. However they will now show up in searches and friends of theirs may want to view their cards. By redirecting all of these views back to the canvas page we can always show the card to their friends.
Once a user has authorized your application they have the ability to create a tab in their profile for your application. These are the tabs you see when you visit one of your friends' profile page. Your can remind users to add this tab. However, it's up to the user to create this tab in the settings panel for your application or with the + sign next to the existing tabs in their profile.
It's important to note here, they have to do that in the Facebook settings panel for your application. You cannot force the creation of that tab through the API or FBML code.
When a user adds a tab for your application you need to define a special page on your server for this tab. The code on this page needs to be a straight FBML page served up to Facebook. However, you can still run the request through a middleware server (such as ColdFusion, JSP, or ASP.
This tab page will be running as a section of the larger
Facebook page so you do not add the regular wrapper HTML to this page; I'm
referring to the <HTML><HEAD><BODY> tags. This is why it
needs to be a different page; however, since all of your logic may be in the
SWF file this could be as simple as a <fb:swf> tag.
Another place that you can run your Flash movie, is on the predefined Boxes tab for the user. The page on this tab has two columns, one wide and one narrow. The user also has the option of taking any item on the Boxes tab and moving into the left side column of their wall page too.
Again, the user controls where they want the box for your application positioned in relationship to all of the other application boxes on this page or on their wall.
The code for the Boxes tab and the Wall page work
differently than the Profile tab. For these pages you need to post the FBML to
Facebook beforehand. You do this with the setFBML() method of the
Facebook API:
var profileWall = "<a href=''><img src='' width='184' height='250' border='0'></a>"; var profileBox = "<a href=''><img src='' width='700' height='250' border='0'></a>"; api.profile_setFBML(api.get_session().uid, profileWide, null, null, profileNarrow, function(){} );
Facebook will then cache the FBML page and serve the content
directly to the user. This moves the server traffic load directly onto the
Facebook servers. However, it also means the data is cached on Facebook and you
need to reset the code with setFBML before Facebook knows about new code.
When you are running Flash inside of an FBML page, either in
an Application tab or your Canvas page, you will launch your Flash application
with the <fb:swf> tag. This is the FBML tag that Facebook uses to control how and when Flash
starts as well as what parameters are passed to the Flash application.
You do have two options of how to invoke this tag. You can do it directly with FBML markup, like so:
<fb:swf swfbgcolor="000000" imgstyle='color:white;" swfsrc='<URL TO YOUR SWF>' imgsrc='<URL TO PLACEHOLDER GRAPHIC>s' width='340' height='270' />
Or you can do it in script with the createElement("fb:swf") tag:
<div id="swfContainer"></div>
<script>
var swf = document.createElement('fb:swf');
swf.setId('my_swf_id');
swf.setWidth('100');
swf.setHeight('100');
swf.setSWFSrc('FULL_URL_TO_MY_SWF');
document.getElementById('swfContainer').appendChild(swf);
</script>
By doing it in script you have the option of dynamically setting up the URL to the SWF, place holder image, or any other parameters of the Flash movie. FBML itself doesn't have the ability to set properties dynamically like you would in Flex with the {Binding} syntax.
Another thing to consider with FBML pages, including the FBML for the Boxes tab and wall, is that Facebook will parse your code before serving it up and rewrite or (as I like to call it) sanitize the code. Specifically, the JavaScript on the page is parsed for unauthorized code and Facebook will also rename functions and variables as needed too. There are a number of JavaScript functions that you are not allowed to run in a FBML page. Facebook will strip these items out to protect their users from potentially harmful application code. An indispensible tool when debugging Facebook applications is the Firefox plug-in, Firebug.
The canvas page is nice and I would recommend it because it gives you full control of how your application runs. Because this page is running in an IFrame, you can run any html or JavaScript that you need.
I've also found that URL parameters passed to the canvas page are passed through to the IFrame; however, I was never able to find a way to get access to these URL parameters in an FBML page, so this is another benefit to using an IFrame page if you can.
To invoke Flash in an IFrame page you have a couple of
choices: You have the Facebook <fb:swf> tag and createElement("fb:swf") option, just like in the FBML page. You can also use the basic <object><embed> tags or a third-party JavaScript library like SWFObject. One thing to note if
you don't use <fb:swf> to invoke the Flash movie, then you will
need to pass in the Facebook URL parameters as flashVars youself (if
you need them).
Here is a simple sample that uses SWFObject and pulls out
any URL parameters and then passes them into the Flash movie as flashVars:
<script src="http://static.ak.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script> <script type="text/javascript"> var api_key = <your api key>; // the xd_reciever.htm file needs to be on your website // relative to your facebook application pages. // For more information: // http://wiki.developers.facebook.com/index.php/Cross-domain_communication_channel var channel_path = 'xd_receiver.htm'; FB_RequireFeatures(["XFBML"], function(){ FB.Facebook.init(api_key, channel_path); }); var queryString = window.location.search; var flashVars = {}; queryString = queryString.substring(1); var fields = queryString.split('&'); var fb_sig_added = 0; for (var i = 0; i < fields.length; i++) { var index = fields[i].indexOf('='); var key = fields[i].substring(0, index); var value = fields[i].substring(index + 1); if (key.toLowerCase() == "fb_sig_added"){ fb_sig_added = value; } flashVars[key] = value; } // first check if they have authorized the app, if not // redirect them to the login page. if (fb_sig_added == 0) { window.parent.location = "http://www.facebook.com/login.php?api_key=" + api_key + "&next=index.htm&v=1.0&canvas=1"; } else { // load the flash movie. swfobject.embedSWF("http://<your domain>/facebook/FacebookClient.swf", "flashContent", "700", "650", "10.0.0", "expressInstall.swf", flashVars, null, null); } </script>
When Facebook runs an FBML or IFrame application there are a
number of parameters available. If you are using the <fb:swf> tag
these will all be passed in as FlashVars automatically.
Note: A complete list of parameters are documented on the Facebook Developers wiki.
Pay close attention to the fb_sig_user, fb_sig_canvas_user,
, fb_sig_profile, fb_sig_profile_user parameters. Depending on the context of when and where your Flash application
is invoked or if the user has authorized your application yet, any one of these
variables could be the Facebook uid of the user using your application.
The Facebook Platform API lets you do a lot, and most of those things are easily doable inside of a Flash application; however, there are still a few things that are FBML only and to the best of my knowledge there is no way to do them through the API from inside of Flash. So for these you will need to put them in the HTML around the Flash movie. Or on another application page altogether. Two of these that I ran into are:
<fb:add-to-profile>: This is the FBML tag that users
need to use to take the FBML you set in Facebook for the Boxes tab and Wall and
actually add that to their Facebook pages; otherwise, users will never see the
FBML you set. <fb:request-form>/ <fb:multi-friend-selector>:
Facebook recently launched a new Friend Selector UI control. Your application
uses this control to allow users to select friends usually to send application
invitations to. You can build your own Friend selector in Flash but you won't
be able to send out Facebook invitations; instead, you'll need to send out your
invitations as Facebook notifications. 
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License
Mike Nimer is the Director of Engineering and Architect of the nomee.com application. Before joining nomee, Mike has spent over a decade building web applications, the servers that run web applications, as well as providing consulting and mentoring help for development teams around the world. Mike was a founding partner of Digital Primates IT Consulting Group, providing mentoring and development support on the Adobe Flash Platform and ColdFusion. Prior to Digital Primates, Mike was a member of the Adobe ColdFusion engineering team where he was responsible, in part, for a number of key features, including PDF generation and the integration of Flex 2 with ColdFusion Server.