Founder and coder for Super + Fun, a social funware company. I also enjoy quilting, reading, and singing in the shower.

Wednesday, October 28th, 2009

Getting started with github

I’m hosting my facebook actionscript demo source code at github. I’ve never used git before, so it’s been a fun learning experience. I managed to get the demo running on a github project page instead of being hosted on an ESC server. I’m not certain I’m taking the best approach, but I have the project setup now with these branches:

becarella/fb_as_connect
|-> master (the demo source code)
|-> gh-pages (the demo project page)
         |-> demo (submodule that pulls from the master branch so I can display the web files hosted there)

I updated the canvas and connect pages for the demo facebook app to pull from the demo submodule.

This post was really helpful in getting the demo submodule setup: http://woss.name/2008/04/09/using-git-submodules-to-track-vendorrails/

I’m going to continue tweaking it and probably frequently break things as I continue to figure out the checkout/commit/merge/push process.

Wednesday, October 28th, 2009

Facebook Authentication with the ActionScript API

I created a little demo app to help me understand Facebook authentication from flash.

Goals

  1. Use only javascript and actionscript, no php or other Facebook client libraries
  2. The secret key is not hardcoded
  3. The same codebase can be deployed on non-Facebook site or in on Facebook app canvas
  4. The app can be used by both authenticated and unauthenticated users
  5. Users can authenticate with Facebook after loading app without reloading the app

The App

If you are logged into facebook and have authorized the app, the demo pulls in your profile picture and user name and displays them in a panel. If you are not logged into facebook or have not yet authorized the app, it shows a login button which will show a popup (from a connect site) or redirect to the login page.

Facebook Connect site embedded as an iframe:

The same app is available as a Facebook iframe canvas page here.

Goal 1: Use only javascript and actionscript, no php or other server-side facebook client libraries

I wanted to use as few languages as possible and maximize what is done from flash. It worked well as described below.

Goal 2: Secret key is not hardcoded

From what I can tell, there’s no way to start a web session solely from the actionscript api (at least not without hardcoding the secret key, which we want to avoid). Instead, the session information can be passed to the swf. In the demo, the actionscript session is created as:

protected function connect(parameters:Object) : void {
    if (parameters.fb_sig_api_key && parameters.fb_sig_ss 
        && parameters.fb_sig_session_key) {
        session = new WebSession(parameters.fb_sig_api_key,
                     parameters.fb_sig_ss, parameters.fb_sig_session_key);
        session.facebook_internal::_uid = parameters.fb_sig_user;
            
        //Create our facebook instance
        facebook = new Facebook();
        session.addEventListener(FacebookEvent.CONNECT, onSessionConnect);
        facebook.startSession(session);
        session.verifySession();
    }
    ...
}

Details on acquiring the session variables are covered under the next goal.

Goal 3: The same codebase can be deployed on a non-Facebook site or on a Facebook app canvas

When loading an app via a Facebook iframe canvas, a number of parameters are appended to the iframe url’s query string, listed here. (The fb_sig_ parameters can also be included using fb:swf on an fbml canvas). In this app, I’ve used javascript to parse the query string into an object and pass to the swf as flashvars on load if the fb_sig_in_iframe=1 parameter is available. The same could be accomplished with a server-side language like php, but I wanted to keep the mix of languages to a minimum.

When loading the app from a Facebook Connect site, the session information is acquired through the javascript Facebook client first, then passed to the swf which sets up its session in the same way as above. In this case, the javascript translates the session variables to the same names used in the iframe query string.

var sessionData = FB.Facebook.apiClient.get_session();
var fbdata = {};
if (sessionData) {
    fbdata.fb_sig_session_key = sessionData.session_key;
    fbdata.fb_sig_ss = sessionData.secret;
    fbdata.fb_sig_user = sessionData.uid;
    fbdata.fb_sig = sessionData.sig;
    fbdata.fb_sig_api_key = api_key;
} 

Goal 4: The app can be used by both authenticated and unauthenticated users

This one is pretty easy: simply do not require a session. Your app will have limited data available, but users who haven’t authorized the app or who don’t have Facebook accounts can still use it if you accommodate them.

Goal 5: Users can authenticate with Facebook after loading app without reloading the app

I had mixed results here. I was unable to get this to work in a canvas page since calls to window.open and FB.Connect.requireSession are ignored in the iframe canvas. Instead, I redirect to facebook.com/login.php if the user needs to log in or authorize the app and then they are returned to the canvas page. This makes some sense since the whole Facebook page needs to refresh if you are logging in.

Logging in from a facebook iframe canvas page:
self.parent.location =  'http://www.facebook.com/login.php?api_key=' + api_key
                         + '&extern=1&fbconnect=1&v=1.0'
                         + '&next=' + escape(CANVAS_PAGE_URL)
                         + '&cancel_url=' + escape(CANVAS_PAGE_URL); 

You can log in without a page refresh in a Facebook Connect site. When the user clicks the “Connect with Facebook” button in the swf, it makes an external interface call to a javascript function. When not in an iframe canvas page, the javascript calls FB.Connect.requireSession. By passing true for the isUserActionHint parameter, the function opens a popup window where the user can login or authorize the app and then closes itself when done.

Logging in via Facebook Connect
FB.ensureInit(function() {
    FB.Connect.requireSession(null, true);  
});

The app page is notified of the status change through the cross domain receiver channel. I initialized the javascript client with a callback for when the user’s logged in status changes. In the callback, the updated session parameters are passed to the swf through another external inteface call.

Initializing the javascript Facebook client:
FB_RequireFeatures(["Api", "Connect"], function() {
    FB.Facebook.init(api_key, 'xd_receiver.html', 
            {   "ifUserConnected": onConnectStatus, 
               "ifUserNotConnected": onConnectStatus
            });   
    });

The Facebook actionscript api docs for the WebSession class recommend using FacebookSessionUtil for managing sessions instead of using WebSession directly. However, FacebookSessionUtil looks for some values only in loaderInfo, which isn’t compatible for updating the session info after the app loads. The demo does use a WebSession instead of FacebookSessionUtil, but it still gets all the necessary information passed in via javascript and doesn’t have hardcoded api or secret keys. The demo doesn’t look for a stored session in a shared object, but it could be added to mimic FacebookSessionUtil closely that way.

Links

View demo using Facebook Connect.

View demo in a Facebook iframe canvas

View and download the source

Reference

Monday, October 26th, 2009

Using System.totalMemory to analyze flash memory usage

When looking for memory leaks on an application that loads many bitmaps, Internet Explorer showed much lower memory usage from System.totalMemory than FireFox.  The difference is because

not everything allocated in the player is allocated by the internal allocator, nor reported through totalMemory…namely anything allocated by OS system calls, memory associated with platform bitmap data, and the JIT buffer associated with the Actionscript VM.”

http://www.justsuppose.com/some-systemgc-and-systemtotalmemory-tips/

Thursday, October 22nd, 2009

White Lies @ Webster Hall: 

<3
White Lies @ Webster Hall:

<3

Saturday, September 26th, 2009

The Killers @ Jones Beach

The Killers @ Jones Beach

Wednesday, September 2nd, 2009

Tuesday, August 4th, 2009

Birthday present from Chris: custom labels!!!: 

Check out www.etsy.com/shop.php?user_id=82743
Birthday present from Chris: custom labels!!!:

Check out www.etsy.com/shop.php?user_id=82743

Wednesday, July 29th, 2009

Jessie&#8217;s makeup bag bday present

Jessie’s makeup bag bday present

Friday, June 26th, 2009