10 links for Facebook developers

Facebook Keegan Street | 25 Aug. 2010 | 5 comments

These are the resources I most frequently refer to while developing Facebook apps. This is by no means an exhaustive list but hopefully it contains something that will help you out.

Official developer’s documentation

Googling for Facebook documentation will often bring you to outdated, incorrect information. Even the official looking wiki.developers.facebook.com contains information that is downright wrong, so stick with developers.facebook.com/docs. Here you can find documentation about everything Facebook: authentication, JavaScript SDK, Graph API, Open Graph protocol, social plugins, FQL, PHP SDK, XFBML and more.

Working examples of Javascript SDK methods and XFBML tags

The best way to learn how these things work is to see some working examples.

Console for testing Graph API queries

If you’re having trouble making Graph API queries from the JavaScript SDK, PHP SDK or some other method, this is a great tool that can help you determine whether the problem is in the query or your other code. It also contains an (almost) exhaustive list of the objects and properties available through the Graph API, but still needs to be updated to include checkins. You can browse through the list and see what information is available to you and the format that it is returned in.

If you see an error message saying "You must use https:// when passing an access token," then change the URL in the input text field from http to https. That’s a bug Apigee needs to fix in its console.

Console for testing FQL queries

FQL queries tend to be more complex than Open Graph queries, so it can be even more valuable to test them out in a console before trying to call them programatically.

URL Linter

If you want your web pages to be shared through Facebook, you will either add Open Graph protocol meta tags or basic meta tags to your pages. No matter which technique you use, the URL Linter can easily show you how Facebook will interpret this metadata when users share your pages.

Developers’ Forum

Draw from the knowledge and experience of over one hundred thousand Facebook developers. Just go easy on the Facebook reps – you can’t expect them to respond to every message or fix every bug. Unfortunately a lot of people tend to be quite disrespectful in the forums.

Bugzilla

The constant innovation of the Facebook platform comes with a price: there is a never-ending backlog of bugs. If you’re banging your head up against the wall because your app isn’t working, more often than not it will be a problem with Facebook’s code rather than yours. Search Bugzilla to find out if other developers are experiencing the same issues as you – and see if or when Facebook plan to fix it.

ThinkDiff.net tutorials

The blog of Md. Mahmud Ahsan contains some really useful tutorials for Facebook development – from getting started with the JavaScript SDK through to advanced topics like using the new iPhone SDK.

Facebook GUI PSD kit

A free set of vector images of Facebook GUI elements like the multi-friend selector and authentication dialogue. Really useful for wireframing and design. Thanks to SurgeWorks for providing this resource.

Unit tests: expose bugs and spend less time fixing them!

Hands-on introduction to creating unit tests that cover your application’s business logic

An extra effort and more code: two major drawbacks that often discourage developers from writing unit tests. They seem hard to write and little to contribute or at least that is what I first experienced when I started using them. And although I still don’t consider myself to be an expert in the field of test-driven development, I have not given up and can say: unit tests are a real time saver. Rather than walking through a long list of benefits, let’s write some code and see for ourselves..

Before you can write a unit test you obviously need to have a chunk of code or some business logic that requires testing. The following example shows you how to add a unit test after writing your initial code and how you can alter the unit test before writing any additional code (e.g. in a second iteration).

Important to note: although the example is created in C# with the Visual Studio unit-testing framework, the principles can be applied to any given library in your preferred programming language.

The full source code of the example can be downloaded here.

Example: Testing the shopping basket of a web shop
Let’s say you are working on a web shop and you are asked to implement some logic that calculates the total price of a shopping basket. You’ve created the shopping basket and price calculation logic in the business tier:

public class WebshopFacade
{
public void AddProductToBasket(ShoppingBasket basket,
Product product)
{
basket.Add(product);
UpdateBasketPrice(basket);
}

public void UpdateBasketPrice(ShoppingBasket basket)
{
double totalPrice = 0;
foreach (ShoppingBasketItem item in basket.GetItems())
{
totalPrice += item.Product.UnitPrice * item.Amount;
}
basket.TotalPrice = totalPrice;
}
}

The code is pretty straightforward: the web shop can create a basket but to add an item it needs to call the façade which will than update the basket’s total price. Now, before creating a web page (and I know you want to) it’s a good practice to set up a unit test. Why? If there are any coding errors in the shopping basket or its price calculation, you want to expose these bugs right now, and not by experiencing strange issues when creating the web page which will eventually have you debug the web application. The unit test may already save you from losing precious time, and surely you want to hold on to it for future testing when the price calculation logic becomes more complicated.

Test method 1: Initial price of the basket
Ok, let’s start out with a basic yet crucial test: you want to make sure that when the web shop creates a basket, the initial total price is zero. You may laugh, but your customers won’t if this is not the case!

[TestClass]
public class ShoppingBasketTest
{
public ShoppingBasketTest()
{
}

[TestMethod]
public void TotalPriceOfEmptyBasketMustBeZero()
{
ShoppingBasket basket = new ShoppingBasket();
Assert.AreEqual(0, basket.TotalPrice, "Expected total price to be zero for empty basket");
}
}

That wasn’t so hard, was it? Running all tests in Visual Studio takes only a few seconds and for me it resulted in a test run completed, results: 1/1 passed. Sweet, an instant confidence boost!

Test method 2: Adding products to the basket
Let’s move on and add a test method that ensures products can be added to the basket:

[TestMethod]
public void ProductsCanBeAddedToTheBasket()
{
ShoppingBasket basket = new ShoppingBasket();
WebshopFacade facade = new WebshopFacade();
MockFactory mocks = new MockFactory();

for (int i = 0; i < 50; i++)
{
facade.AddProductToBasket(basket, mocks.CreateProduct());
}

int totalUnits = 0;
foreach (ShoppingBasketItem item in basket.GetItems())
{
totalUnits += item.Amount;
}

Assert.AreEqual(50, totalUnits, "Expected 50 units in the basket after adding 50 random products");
}

In this test 50 random products are added to the basket, and then the test does a recount by looping through the basket’s items. As the test method cannot create products directly (nor can the web shop for that matter) a mock factory is used to create mock objects, in this case products.

And believe it or not, when I first ran the test it failed because of a bug in the basket. In Visual Studio you can add a breakpoint inside any test method and instantly debug the test method, so I was able to resolve the issue in no time!

Test method 3: Price calculation
Finally, you can add a test method which ensures the total price is calculated correctly:

[TestMethod]
public void BasketTotalPriceIsCalculatedCorrectly()
{
ShoppingBasket basket = new ShoppingBasket();
WebshopFacade facade = new WebshopFacade();
MockFactory mocks = new MockFactory();

double expectedTotal = 0;
for (int i = 0; i < 50; i++)
{
var product = mocks.CreateProduct();
facade.AddProductToBasket(basket, mocks.CreateProduct());
expectedTotal += product.UnitPrice;
}

Assert.AreEqual(Math.Round(expectedTotal, 2),  Math.Round(basket.TotalPrice, 2), "Expected total price does not match basket's total price");
}

The code is mostly copied and pasted from the previous method, but here the price calculation is somewhat mimicked. It may seem obvious that this test will pass, but when you make further progress in developing the basket, this test method can fail, and it will expose any bugs that were introduced by your (or someone else’s) changes.

Another way of testing this logic would be to create some specific products, and to hard code the expected total price. This could include special situations that don’t frequently occur but are part of the business logic, e.g. discounts for certain products, discounts for a specific amount of products, etc.

Creating a unit test before writing any code
The unit test now covers the basic functionality of the basket and you might decide to start a second iteration in which you introduce removal of products or discount logic. In either case you can initiate this iteration by creating new unit tests or updating the existing one allowing you to focus on the requirements before writing any code.

You can start by changing the “interface” of the façade, by adding a method for product removal:

public void RemoveFromBasket(ShoppingBasket basket,
Product product)
{
throw new NotImplementedException();
}

And now you can add new test methods that validate the product removal logic:

[TestMethod]
public void ProductsCanBeRemovedFromTheBasket()
{
ShoppingBasket basket = new ShoppingBasket();
WebshopFacade facade = new WebshopFacade();
MockFactory mocks = new MockFactory();

var addedProducts = new List
();
for (int i = 0; i < 50; i++)
{
var product = mocks.CreateProduct();
facade.AddProductToBasket(basket, product);
addedProducts.Add(product);
}

for (int i = 0; i < 25; i++)
{
var remove = addedProducts[i];
facade.RemoveFromBasket(basket, remove);
addedProducts.Remove(remove);
}

int totalUnits = 0;
foreach (ShoppingBasketItem item in basket.GetItems())
{
totalUnits += item.Amount;
}

Assert.AreEqual(25, totalUnits, "Expected the basket to have 25 remaining units after removal");
}
[TestMethod]
[ExpectedException(typeof(ShoppingBasketException), "Expected shopping basket exception to be thrown")]
public void ProductMustExistInBasketOnRemoval()
{
ShoppingBasket basket = new ShoppingBasket();
WebshopFacade facade = new WebshopFacade();
MockFactory mocks = new MockFactory();

facade.RemoveFromBasket(basket, mocks.CreateProduct());
}

Obviously the unit test will fail if you run it before you have written the actual implementation, but for sure you will gain a great deal of insight in how to set up any interfaces, how objects should behave or interact, how exceptions are thrown, etc.

Try it out yourself!
A demo, including the example’s full source code can be downloaded here. You can run the tests in Visual Studio by pressing CTRL-R A or through the menu as shown in the screenshot below. If you are new to unit testing and can use a little practice, I strongly recommend that you try and write the code for product removal, and see if you can make the failing unit test pass again.

Final considerations
• Any unit tests that you create are there to stay and the more complex a module becomes the more often you will find that bugs are exposed when the module is changed or re-factored, simply by rerunning the tests
• By creating advanced unit tests you are to mimic and validate every possible in- and output of a certain module, allowing you to immediately recognize and debug the most specific / exotic situations when a test fails
• Unit tests may seem like a lot of code to write, but most of the time you are just writing the consuming code that has to be implemented anyway
• Unit tests offer great insight in how a module behaves or is to be used. Developers that are not familiar with the code can walk through the tests as it were code documentation

Hope this helps!

Publishing Facebook stories on browsers with popup blockers

Facebook Keegan Street | 11 Aug. 2010 | 2 comments

How to use Facebook’s Stream.Publish method on browsers with popup blockers. See a demo.

What is the problem?

Recently many Facebook developers have been frustrated by popup blockers preventing the Stream Publish dialogue box from being displayed. If a user hasn’t logged in and authorised the application, dialogue boxes are shown in a popup window instead of an iframe. That’s fine for some visitors, but for those who have a popup blocker enabled, it means that they won’t see the dialogue box and therefore can’t publish a post into the stream.

The Stream Publish dialogue being displayed in an iframe.
The Stream Publish dialogue being displayed in an iframe.

The Stream Publish dialogue being displayed in a popup window. Popup blockers will prevent this from opening.
The Stream Publish dialogue being displayed in a popup window. Popup blockers will prevent this from opening.

What causes it?

Previously popup blockers didn’t cause any problems for the Stream Publish method because all dialogue boxes were displayed with an iframe rather than a popup window. But in mid-May Facebook discovered that this exposed users to a clickjacking security vulnerability. To address the security problem, dialogue boxes are now shown in a popup window instead of an iframe for users who are not logged in or haven’t authorised the application making the request. According to Facebook, this change is here to stay.

Technically, popup blockers shouldn’t block popup windows that are opened intentionally by the user, for example by clicking on a link that says "Publish this to your profile". Unfortunately however, Facebook have implemented their Stream Publish method in such a way that the relationship between the user action and the popup window being opened is not direct enough. The onus is on Facebook to fix this, but in the meantime, there is a workaround.

The workaround

While not documented by Facebook, it is very easy to construct a URL for the Stream Publish dialogue box. To publish the news feed story, the user simply has to click a link pointing to this URL. Here’s one I prepared earlier. You can construct the URL with your programming language of choice, but I will demonstrate how it works with an ActionScript 3 example. (I have also provided a PHP example in the source download).

1. Defining the post parameters

First we define the parameters for the post, such as the title, link, caption and any media that we want to attach. The attachment and action_links objects follow exactly the same structure as the JSON objects used by the streamPublish method in the JavaScript SDK and the old REST API.

// An event handler which publishes a Facebook story when a button is clicked
private function clickPost(event : MouseEvent) : void {
    // Define the stream story parameters
    var attachment:Object = {
        'name' : "I've just played golf with Lexus at St Andrews.",
        'href' : 'http://apps.facebook.com/myapp',
        'caption' : "Win 2 x VIP tickets to the Open Golf Championships at St Andrews. Simply find the missing golf ball to win - it's quick and fun! Play now...",
        'media' : [ {'type' : 'image', 'src' : 'http://www.myapp.com/assets/share_image.jpg', 'href' : 'http://apps.facebook.com/myapp'}]
    };
    var action_links:Object = [
        {'text' : 'Find the Golf Ball', 'href' : 'http://apps.facebook.com/myapp'}
    ];
    var publishURL:URLRequest = StreamPublish.publishStoryLink('YOUR_API_KEY', attachment, action_links, TopGoals.APP_TAB_URL);
    // Open the URL and Facebook's dialogue box will be displayed
    navigateToURL(publishURL, "_blank");
}

2. Generating the URL

This static method takes the parameters we defined in the previous step and encodes them into a URL. It uses the JSON class from Mike Chambers’ as3corelib project.

package com.thesedays.facebook {
    import flash.net.URLRequest;
    import com.adobe.serialization.json.JSON;

    public class StreamPublish {
        
        /**
         * Generate a URL for displaying the Stream Publish dialogue.
         *
         * @param api_key The API key of your application - you must create an application to call this method.
         * @param attachment An object containing the post text, links, media, etc.
         * @param action_links An object containing actions links of text and hyperlinks.
         * @param next The URL to open after the user has published the post or cancelled it.
         * @param locale The locale code to display the Facebook interface with, for example en_US, fr_FR or nl_NL. It is generally best to leave this parameter as null because then Facebook will determine the language based on the user's browser and session.
         */
        public static function publishStoryLink(api_key:String, attachment:Object, action_links:Object, next:String, locale:String = null) : URLRequest {
            var url:String = 'http://www.facebook.com/connect/uiserver.php' +
            (locale ? '?locale=' + locale + '&' : '?') +
            'api_key=' + api_key +
            '&method=stream.publish' +
            '&channel=' + escape('http://www.facebook.com/xd_receiver_v0.4.php') +
            '&extern=1' +
            '&attachment=' + escape(JSON.encode(attachment)) +
            '&action_links=' + escape(JSON.encode(action_links)) +
            '&display=popup' +
            '&next=' + escape(next);
            return new URLRequest(url);
        }
    }
}

Download the source from this example.

Why Umbraco suits us

It has only been a couple of months since we first started using Umbraco, an open-source CMS built on top of the .NET platform, and a lot of my colleagues will agree when I say that we have grown extremely fond of it. Why, you ask? Well, let me explain a few things.

Finding the right CMS is a challenge

Finding a CMS that suits your needs – not to mention fully embracing one – is not an easy task. It is hard to get your hands on a descent comparison and research is very time consuming as you really need to get your hands dirty. If you are somewhat wary and cautious about using a CMS, you are right, it is to be a tool that assists you in creating and maintaining websites, and it should never dictate the way you handle things as you probably already have a methodology or framework in place. And that is exactly what we have found in Umbraco: a reliable, user-friendly and extensible platform which drastically reduces development time and really fits into our projects.

Umbraco is easy, extensible and reduces development time

After completing several projects with Umbraco, we are very pleased with the results and would like to emphasize the following:

  • Umbraco is easy to learn. Within days you are able to grasp its concept and developers will be writing custom XSLT for dynamic content such as a news pages, FAQ’s, ..
  • As Umbraco is based on ASP.NET, most developers will be very familiar with the environment and configuration settings which eases development and deployment
  • Umbraco has an active community: http://our.umbraco.org/
  • A project can be implemented without writing a single line of .NET code. You may have to write some XSLT or install a package, but you will save a considerable amount of development time nonetheless
  • Umbraco is extensible in many ways, from writing custom XSLT and .NET user controls to installing packages and integrating its API or event-driven model.

Most importantly, its extensibility allows us to choose which parts of an application we wish to implement using Umbraco while we are still able to implement the parts we don’t see fit in the exact same way we would implemented these in other situations.

Completed projects

Although we still have several projects in the pipeline, we would already like to share some of the projects that have been fully implemented using Umbraco:

Plans for the future

We plan to do much more with Umbraco, and the first thing we want to do now is tweak our development environment and make Umbraco integration even easier:

  • Add an abstraction layer to our framework that will abstract the Umbraco API integration and provides a set of global helper classes for Umbraco
  • Create a template solution for Visual Studio that contains a pre-configured Umbraco install and includes our framework projects
  • Moving the template solution to Microsoft’s Web Platform Installer, allowing our developers to install the latest version of the template in no time. See also: http://bit.ly/aj2Uwm

As you can see, many of us have become strong believers and if you are considering using Umbraco as your CMS or you are a strong believer yourself we are always glad to hear from you.

An easy way to detect mobile devices

So you want to deploy a mobile version of your website? You’ve thought about what your target users would do with a mobile version, written your content, created your design and developed your Flash or HTML, CSS and Javascript (if you haven’t done that yet, read this post instead). Now for the task that can seem most daunting to new mobile web developers — detecting devices and serving the correct version of your site. How do you ensure that users with mobile phones will see the mobile version and vice versa?

The answer: WURFL. The Wireless Universal Resource File (WURFL) is an open source project which collects information about all of the different mobile devices in use. It is constantly being updated, so as long as you keep your WURFL definitions up-to-date you don’t have to worry about your detection scripts not recognising new devices. By querying a WURFL database with your visitor’s User Agent string, you can not only determine whether the device they are using is a mobile device, but whether it has a touch screen, can make phone calls, is a tablet (iPad) and more.

It is reasonably straightforward to install a Tera-WURFL service on your PHP enabled web server. If download speed is critical for your website, it would be best to install Tera-WURFL on the same web server. But if you would prefer to avoid the installation process, feel free to use our quick and easy These Days implementation of Tera-WURFL.

It can be as simple as this:

<?php
require_once ('TeraWurflRemoteClient.php');
$wurflObj = new TeraWurflRemoteClient(
    'http://wurfl.thesedays.com/webservice.php' );
$wurflObj->getCapabilitiesFromAgent(null, array('product_info'));
if ($wurflObj->getDeviceCapability("is_wireless_device")) {
    // Show mobile website
} else {
    // Show normal website
}
?>

Don’t forget to give your users a way of overriding automatic device detection. Even WURFL can get it wrong sometimes, and anyway some users prefer to view full sites on their mobile phones. The user is king!

Switch to our mobile site