Facebook.. Could you live without facebook nowadays? Sometimes I’m happy when I don’t get anything on facebook, just to have a bit of peace and quiet of it.
Well, nevertheless, I’m writing this article because I’ve seen this post on the Adobe Forums by dmennenoh where he asked for the possibilities of using the Facebook AS3 API without Flex or AIR and the possibility of uploading pictures to Facebook.
Short answer: yes, it’s possible but…. it’s not a very well documented process of achieving it.
Before we start, I would like to recommend you a few tutorials on the Adobe Developer Connection, Jeanette Stallons wrote a whole series about the usage of the Facebook AS3 API, and it’s an absolute must read if you want to start developing flash applications or websites using facebook data and connectivity. First I recommend you starting with the Quick Start to get a feeling for it, after that move on to Part 1: Build and Test Locally, Part 2: Deploy on Facebook and Part 3: Deploy using Facebook Connect
First of all before we start be sure to get the newest FacebookAS3 library, be sure to download the Flash version of it. At this point the current version is Facebook_library_v3.4_flash.swc you can get newest version on the Project page.
As I prefer using MinimalComps by Keith Peters (aka. BIT-101) we are going to download his classes here. If you don’t know MinimalComps, it’s a set of components like you know from Flex or the Flash IDE, it contains the default set of components like button, textfield, textarea, but also has various interesting components like dials, calendars, knobs and much much more. I strongly recommend you read through the documentation and work through a few tutorials so you get your hands dirty with it.
Again this is not a MUST-USE, I just feel more comfortable using these then any other components.
I strongly recommend to use the deMonsterDebugger to trace events and data returned from facebook, it has a simple to use interface and is far better then the normal trace() functionality.
1. Setup
1.1 Let’s start by opening Flash Builder and creating a new Actionscript Project with the name FacebookAS3. We are not going to use any Flex Components neither any AIR methods, you could also build this in the Flash IDE, but I prefer to use Flash Builder for it’s Code Completion features and it’s the tool I prefer when coding AS3.
1.2 Import the .SWC file by right clicking on the Project name and selecting Properties, then go to Actionscript Build Path and select the Library path tab, press the Add SWC button and locate the downloaded facebook_library_flash.swc you downloaded previously. Press OK and we are ready to go.
1.3 If you using MinimalComps for the UserInterface, don’t forget to import the source to your project so you can use them properly.
1.4 If you using deMonsterDebugger to trace and debug your application, don’t forget to import the needed classes to your project src folder.
2. Login
Below you will find my main class that handles the whole login procedure of our small application.
public class Main extends Sprite { private static const API_KEY :String = "xxxxx"; private static const SECRET :String = "xxxxx"; private var _overlaySprite :Sprite; private var _userInterface :UserInterface; private var _photoBA :ByteArray; private var _fb :Facebook; private var _fbSession :FacebookSessionUtil; private var _userData :FacebookUser; private var _uid :String; private var _batchCollection :BatchCollection; private var _batchRun :BatchRun; private var _albumArray :Array; private var _uploadPhoto :UploadPhoto; public function Main() { MonsterDebugger.trace(this, "init - Facebook integration" ); stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; _overlaySprite = new Sprite(); _overlaySprite.graphics.beginFill(0xcccccc, 0.5 ); _overlaySprite.graphics.drawRect( 0, 0, stage.stageWidth, stage.stageHeight ); _overlaySprite.graphics.endFill(); addChild( _overlaySprite ); _overlaySprite.visible = false; _userInterface = new UserInterface(); _userInterface.addEventListener( Event.SELECT, uploadImage ); addChild( _userInterface ); _userInterface.visible = false; login(); } private function login():void { _fbSession = new FacebookSessionUtil( API_KEY, SECRET, loaderInfo ); _fb = _fbSession.facebook; _fbSession.addEventListener( FacebookEvent.CONNECT, connectHandle ); _fbSession.addEventListener( FacebookEvent.WAITING_FOR_LOGIN, loginWaitHandler ); _fbSession.login(); } private function connectHandle( e:FacebookEvent ):void { if ( e.success ) { _uid = ( e.data as GetSessionData ).uid; _batchCollection = new BatchCollection(); _batchCollection.addItem( new HasAppPermission( HasAppPermissionValues.PHOTO_UPLOAD ) ); _batchCollection.addItem( new GetInfo([_uid], [GetInfoFieldValues.FIRST_NAME, GetInfoFieldValues.CURRENT_LOCATION])); _batchCollection.addItem( new GetAlbums() ); _batchRun = _fb.post( new BatchRun( _batchCollection ) ) as BatchRun; _batchRun.addEventListener( FacebookEvent.COMPLETE, batchCompleteHandler ); } } private function batchCompleteHandler( e:FacebookEvent ):void { if ( e.success ) { var results:Array = ( e.data as BatchResult ).results; var hasPermission:BooleanResultData = results[0]; var getInfoResult:GetInfoData = results[1]; var getAlbumsResult:GetAlbumsData = results[2]; if ( !hasPermission.value ) { MonsterDebugger.trace(this, "no permission" ); getPermissions(); } /*_userData = getInfoResult.userCollection.getItemAt(0) as FacebookUser; _userInterface.username = _userData.first_name + _userData.last_name; _userInterface.albumList = getAlbumsResult.albumCollection.toArray();*/ } } private function getPermissions():void { _fb.grantExtendedPermission( ExtendedPermissionValues.PHOTO_UPLOAD ); } private function uploadImage( e:Event ):void { _uploadPhoto = new UploadPhoto(_userInterface.snapshot); _fb.post(_uploadPhoto); } private function loginWaitHandler( e:FacebookEvent ):void { _overlaySprite.visible = true; _overlaySprite.addEventListener( MouseEvent.CLICK, confirmConnect ); } private function confirmConnect( e:MouseEvent ):void { _overlaySprite.visible = false; _userInterface.visible = true; _overlaySprite.removeEventListener( MouseEvent.CLICK, confirmConnect ); _fbSession.validateLogin(); } }
Let’s take a look at what’s happening here, first of all we create instances of the facebook and the facebooksessionutil classes, those are going to help using Facebook throughout the whole application.
We setup an overlaysprite (this could also be a simple button or an alert panel) that will let us know when the user came back from the facebook login page. When the overlaysprite is clicked we validate the login and enable our userinterface. When the user is connected successfully to the application we start our BatchCollection to make multiple calls to FB, We check if the user has allowed permission to upload pictures, get his basic information like id, name and so on, and also get the album list from his profile (currently not working due to API bug)
When the batch is completed we assign the result to various variables and check the status of the extended permission if this is false, then we ask the user to confirm the permission so we are able to upload pictures, the getPermission() method.
After that we are ready to move on to our interface.
In this example I’m not going to create a seamless experience with Facebook that you know from other applications mostly on Mobile Phones, that involves a bunch of HTML and Javascript scripting and is covered on Jeanette Stallons Part 3: Deploy using Facebook Connect
3. Interface (UserInterface.as)
Next up we are going to create a simple interface so you can preview the webcam image and take a snapshot, we also going to create a small logger window so we get informed about what’s going on without having to switch to the deMonsterDebugger to view the status. Therefore I’m going to create a custom class named UserInterface which will have the visual assets and placeholders for the data received.
Below the Userinterface.as class:
public class UserInterface extends Sprite { private var _video :Video; private var _camera :Camera; private var _bitmap :Bitmap; private var _bitmapData :BitmapData; private var _snapshotBA :ByteArray; private var _pushButton :PushButton; private var _albumArray :Array; private var _albumList :List; public function UserInterface() { _camera = Camera.getCamera(); _camera.setMode( 640, 480, 25, true ); _video = new Video( _camera.width / 2, _camera.height / 2 ); _video.attachCamera( _camera ); addChild( _video ); _pushButton = new PushButton(); _pushButton.width = 80; _pushButton.x = _video.width - _pushButton.width; _pushButton.y = _video.height + 5; _pushButton.label = "CAPTURE"; _pushButton.addEventListener( MouseEvent.CLICK, createSnapshot ); addChild( _pushButton ); _bitmapData = new BitmapData( _camera.width / 2, _camera.height / 2 ); _bitmap = new Bitmap( _bitmapData ); } private function createSnapshot( e:MouseEvent ):void { _bitmapData.draw( _video ); _video.visible = false; addChild( _bitmap ); var enc:JPGEncoder = new JPGEncoder( 80 ); _snapshotBA = enc.encode( _bitmapData ); _pushButton.removeEventListener( MouseEvent.CLICK, createSnapshot ); _pushButton.label = "UPLOAD IMAGE"; _pushButton.addEventListener( MouseEvent.CLICK, sendSnapshot ); } private function sendSnapshot( e:MouseEvent ):void { dispatchEvent( new Event( Event.SELECT ) ) } private function createList():void { _albumList = new List( this, _video.x + _video.width + 20, _video.y, _albumArray ); addChild( _albumList ); } public function set albumList( arr:Array ):void { _albumArray = arr; //MonsterDebugger.trace(this, _albumArray ); //createList(); } public function get snapshot():ByteArray { return _snapshotBA; } }
As you see I’m creaing a Camera instance with the size of 640x480px and attaching it to a video class to be displayed on the stage at halfsize, you could also keep it the full size but I prefer working with the 320×240 format.
The Bitmap and BitmapData instances are created and create a getter to return the bytearray to our mainapplication.
4. Using the Webcam
Let’s take a quicklook what we are doing to take a snapshot of the webcam and how to prepare the image to be uploaded to Facebook. As mentioned on my previous post we take a snapshot of the webcam by creating a bitmapdata of it, then we use the JPGEncoder classes from the AS3Corelib (these are as well already inside the AS3Facebook Library) and encode them into a ByteArray.
private function createSnapshot( e:MouseEvent ):void { _bitmapData.draw( _video ); _video.visible = false; addChild( _bitmap ); var enc:JPGEncoder = new JPGEncoder( 80 ); _snapshotBA = enc.encode( _bitmapData ); }
5. Choosing Album and uploading Picture
As mentioned before there is currently a bug with the AS3Facebook API 3.4, you cannot get the Albumlist from the logged in user, even if you give the application the proper extended permissions. So in our case we are just going to upload our photos to the default album, now you’re asking what’s the default album?
It’s not very clear to me as well, but basically Facebook creates a Photoalbum for every application that uploads an image to it, let’s say your application is called “APU” the user using the application will get a APU PhotoGallery folder in his profile. So choose wisely what name your application will have.
Below the upload code:
private function uploadImage( e:Event ):void { _uploadPhoto = new UploadPhoto(_userInterface.snapshot); _fb.post(_uploadPhoto); }
That’s it, the most difficult part developing applications using Facebook is barely the way the whole data communication works, the API is very stable and things work well ( let’s forget the GetAlbum bug ).
Most tutorials out there have been written for Flex or AIR, simply because it gives you the best userinterface to handle FB needs nevertheless I prefer using pure AS3.
This time I didn’t want to create a nice interface to use it, as this is solely a programming article, feel free to modify it, download it, share it, whatever you would like to do with it.
You can download the project here: Source (Flash Builder Project)

The AS3 & Facebook: Uploading Webcam Photos by Tiago's Weblog, unless otherwise expressly stated, is licensed under a Creative Commons Attribution 2.5 Switzerland License.



Funny that you should publish this now, I spent the last week figuring this out by myself
I ended up doing the exact same thing (besides the batch, thanks for the tip), however I end up with a signature error as a response from Facebook when sending the image. Have you faced anything similar?
Hm.. nope never run into that problem, can you post the exact error? I think it has something to do with the authentication of the app or even the permissions.. Is your app on facebook set for desktop or web deployment?
My app is in a canvas page (web), I have a lot of extended permissions allowed already (status_update,photo_upload,video_upload,create_note,share_item,publish_stream,user_photos).
After testing a lot, it turns out that sometimes the UID is mandatory and sometimes not, I find that quite uneven.
For example, for creating the album, if I do not use it, it fails, whereas in uploading a photo, if I use it, it fails. Funny, if I also omit the argument (which is defaulted as null) it fails, but if I actually pass null, then it works.
In the end, I can now upload the image, it was just a bit of black muddy magic around it
yeh the FB AS3 API is or let’s say the FB API itself, is kind of quirky, I’m looking forward to the next implementation with the graph api.. that one is more stable and has a clearly defined structure, it’s even based on oauth which should make our lifes easier
Hi
can i use Adobe flash CS4 to create this application?
& i cant download the source codes that’s given above. May i know why?
Hi Jess, yes the .as classes and document class also do work with flash, you just need to take care of which API version to download.
& the download is working again.. sorry there was a small typo.
Hi Tiago, thanks so much!
im actually quite new in flash. For this application, it doesnt need an fla. file?
Because normally the flash(CS4) file created needs an fla file to debug.
& API version means the API key?
Sorry for questioning so much ~
Dont quite understand how this works with Flash CS4.
@Jess: The application was built with Flash Builder 4, so there is no .fla file involved. .fla files are only generated by the Flash IDE (Flash CS..) What you need to do is use my main class as your document class by clicking on the stage and set the document class in the properties panel. you should be aware that all the files in my zip need to be in the same location as the .fla file, otherwise it will not work as expected.
Regarding the API version, if you go have a look at the google code page you will be presented with 2 API versions (Flex & Flash) you just need to download the Flash version as Flex will not work for you.
The API key has nothing to do with this app besides of enabling your application talk to facebook.
Hope it helps
Respected Sir,
Will it work on flash cs3 ide? I have used the Main.as file as a document class and also added the facebook component and kept it on the library. But still when I am publishing it nothing is happening. I am publishing it on flash player 9 version I ahve also used flash cs4 ide and player 10 but still not working and showing error. Please help me.
I have one more question. Can I call the facebook album by using Flash cs3 Ide and this facebook component. Do you have any example? or can you provide me any code or ref link?
waiting for your reply.
Hi i think your web is quite good you know.