Fundamentals of building a Flex Facebook application

Fundamentals of building a Flex Facebook application

Unfortunately the Facebook developer documentation is very confusing and it’s missing some very basic information. So i decided to write this how to. It’s about building a Flex application which is running in the Facebook Canvas. (You probably use Canvas if your application is running inside of Facebook) Moreover it will retrieve the name of the logged in user. The crux is to get the User session into the Flash application in order to make calls via the Actionscript 3 API, which his is very easy if you know how ;)

04_swf_fbmlfull

First you’ll have to set up a developer account on Facebook and your own application. It is essential that you set a “Canvas Callback URL” (Facebook pulls the content for your application’s canvas pages from this URL – step 2 in the scheme above). The “Render Method” must be set to FBML.

Your Server (where the Canvas Callbak URL points to), has to output FBML tags and/or HTML and JS/FBJS. In order to insert a Flash Movie into your Canvas page, it is enough to print out the SWF FBML tag:

 <fb:swf swfsrc="http://absolute-path-to-your-swf-file.swf"/>

If you navigate to your application now (http://apps.facebook.com/nameofyourapp), you should see your Flash movie. But how to get your name printed out in the Flash movie? This is where the documentation has some vacancies…

Looking at the documentation you could think you’d have to use the ActionScript 3 Facebook Library from adobe. This  is right. Please follow the tutorial on the Adobe website to build your first Facebook Flash application. When you’re finished you’ll notice that it always tries to open a new window where you have to login to facebook and than you have to click a button in your app. This is not what we want if our application is running inside Canvas because there the user is already logged in into Facebook. But this code anyways tries to open a window to log you in. In this case it doesn’t even work! So how can i get the session from the canvas into my Flex app?? The <fb:swf/> tag automatically passes a FlashVar containing the session into our application! In order to use it to establish a connection to the api you have to use the following code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
backgroundColor="white" backgroundImage=""
applicationComplete="init()">
<mx:Script>
<![CDATA[
import mx.events.CloseEvent;
import com.facebook.data.users.FacebookUser;
import com.facebook.data.users.GetInfoData;
import com.facebook.data.users.GetInfoFieldValues;
import com.facebook.commands.users.GetInfo;
import com.facebook.net.FacebookCall;
import mx.controls.Alert;
import com.facebook.events.FacebookEvent;
import com.facebook.Facebook;
import com.facebook.utils.FacebookSessionUtil;

private var session:FacebookSessionUtil;
private var fBook:Facebook;
private var user:FacebookUser;

private function init():void
{
session = new FacebookSessionUtil("API_KEY","API_SECRET", loaderInfo);
session.addEventListener(FacebookEvent.CONNECT, onFacebookConnect)
fBook=session.facebook;

if (loaderInfo.parameters.fb_sig_session_key) {	// Session is beeing passed from the Canvas page
session.verifySession(); // Connect to API
} else {
session.login(); // Debugging in Flash CS4 - This works offline using the popup to login
Alert.show("Wait for the window to open, login to Facebook and then klick Yes","Login",1,null,verifySessionHandler);
}
}

// verify session in opened window
private function verifySessionHandler(e:CloseEvent = null):void {
session.validateLogin();
}

// make an api call when connected
private function onFacebookConnect(e:FacebookEvent):void{
var call:FacebookCall=fBook.post(new GetInfo([fBook.uid],[GetInfoFieldValues.ALL_VALUES]));
call.addEventListener(FacebookEvent.COMPLETE,onGetInfo);
}

// when the GetInfo call comes back:
private function onGetInfo(e:FacebookEvent):void{
user=(e.data as GetInfoData).userCollection.getItemAt(0) as FacebookUser;
title.text="Hello "+user.first_name+" "+user.last_name;
}

]]>
</mx:Script>

<mx:Label id="title" text="loading..."/>

</mx:Application>

As you can see it is very simple :) But there are still some problems. Try to remove the permissions for your app and then browse to your app. It will NOT ask you for permissions to access your data on Facebook, it will load the swf and the swf will try to open a new window/is showing that alertbox (Wait for the window to open, login to…). Whats going wrong now?? Facebook does not pass the session to your Flex app, because the required permissions are not granted. But how to open that Facebook dialogue that asks for these permissions? You’ll need some more FBML tags to do that:

<?php
if(isset($_GET[installed]) && $_GET[installed] == 1)
header("Location: http://apps.facebook.com/goltergaul");
?>
<fb:if-is-app-user>
<fb:swf swfsrc="http://root.goltergaul.de/fbtest/facebooktest.swf"/>
<fb:else>
<fb:redirect url="http://www.facebook.com/tos.php?api_key=api_key&v=1.0" />
</fb:else>
</fb:if-is-app-user>

This code does the following: If the user did not grant permission yet (you test that with the <fb:if-is-app-user> tag) you redirect to http://www.facebook.com/tos.php?api_key=api_key&v=1.0 using the redirect tag. At this url the client will be prompted to grant permissions. If he does he is redirected to your server and a few GET parameters will be appended to the url, in this case ?installed=1 is appended, which is being checked by the php code. So the user is redirected back to your application where now the if-is-app-user tag will recognise it and display the Flash movie.

One more problem i had was to post something on the users stream. I did not want to post it via the API using ActionScript 3, i wanted a Facebook window to open where you can enter a comment and post it. (Happy Aquarium and Farmville do it the same way). In order to do this you have to call a Javascript function from your Flash movie. This can be done by using LocalConnections. You also have to change your FBML once again to:

 <?php
if(isset($_GET[installed]) && $_GET[installed] == 1)
header("Location: http://apps.facebook.com/goltergaul");
?>
<fb:if-is-app-user>
<fb:fbjs-bridge/>
<fb:swf swfsrc="http://root.goltergaul.de/fbtest/facebooktest.swf"/>
<fb:else>
<fb:redirect url="http://www.facebook.com/tos.php?api_key=api_key&v=1.0" />
</fb:else>
</fb:if-is-app-user>
<script><!-- --></script>

As you can see i added a fbjs-bridge tag and an empty script tag. This way Facebook will prepare everything so that calls from your movie can be accepted. Note that the script tag cannot be totally empty, because otherwise Facebook will delete it. In addition the fbjs tag has to be right before the swf tag!

Add the following Code to your Flex app:

private var connection:LocalConnection = new LocalConnection();
private var connectionName:String;

private function init():void
{
session = new FacebookSessionUtil("API KEY","API SECRET", loaderInfo);
session.addEventListener(FacebookEvent.CONNECT, onFacebookConnect)
fBook=session.facebook;

if (loaderInfo.parameters.fb_sig_session_key) {
session.verifySession(); // Deploy in Facebook Canvas iframe
connectionName = loaderInfo.parameters.fb_local_connection;
} else {
session.login(); // Debugging in Flash CS4
Alert.show("Wait for the window to open, login to Facebook and then klick OK","Login",1,null,verifySessionHandler);
}
}
private function callFBJS(methodName:String, parameters:Array):void {
if (connectionName) {
connection.send(connectionName, "callFBJS", methodName, parameters);
}
}

Now you are able to open such a Facebook window by calling callFBJS(’Facebook.streamPublish’, []);

Hope this helped you :)

About the Author

Studying MultimediaTechnology in Salzburg, Austria