Implementing Facebook

This guide discusses how to implement common Facebook tasks and processes in your Corona app.

Overview

Corona SDK offers two different ways to work with Facebook:

  1. The Social Plugin.
  2. The Facebook plugin.

If you need to perform simple tasks like posting a status update to a Facebook user's timeline, the Social Plugin is the easiest way to accomplish this. If you want to perform more advanced tasks, you'll need to use the Facebook plugin, discussed in detail starting with the Facebook Plugin section below.

Social Plugin

The Social Plugin is used to implement features similar to the typical iOS sharing menu, where you can email, send an SMS/text message, print, or share to Twitter or Facebook. Corona supports facilities to handle email, SMS/text, and native support for Twitter and Facebook.

To use the Social Plugin, be aware of the following important points:

  1. You are not required to set up anything with Facebook.
  2. The end user must be using an iOS device with iOS 6.0 or later.
  3. The end user must have core Facebook support enabled on the device.
  4. You must include the Plugin in your build.settings file (see below).

Including the Plugin

The Social Plugin uses Corona's standard plugin framework. Thus, you must include it within the plugins table of build.settings:

settings = {

    plugins =
    {
        ["CoronaProvider.native.popup.social"] =
        {
            publisherId = "com.coronalabs"
        },
    },
}

Showing the Popup

To show the native popup in your app, use native.showPopup() with "social" as the first parameter:

native.showPopup( "social", options )

For the second parameter, options must be a Lua table containing information to pre-populate the form, for example:

local options = {
    service = "facebook",
    message = "Check out this photo!",
    listener = eventListener,
    image = {
        { filename = "pic.jpg", baseDir = system.ResourceDirectory },
        { filename = "pic2.jpg", baseDir = system.ResourceDirectory }
    },
    url = "http://coronalabs.com"
}
  • service — this is the service you want to use. Valid string values include "facebook", "twitter", or "sinaWeibo".
  • message — an optional string that specifies the text of your status post.
  • listener — an optional function to process the return value of the call.
  • image — an optional table of images to upload with the post. Each entry is a table with key members: filename and baseDir which specifies the directory constant where the image is located.
  • url — either a single URL to include in the post, or an array of strings if you have multiple URLs.
Important

To ensure that the end user can access the native feature on their device, you can check by calling native.canShowPopup(). In this instance, use "social" as the first parameter and the desired service name (string) as the second parameter.

local isFacebookAvailable = native.canShowPopup( "social", "facebook" )

If this call returns true, the user is on an operating system that supports the feature and he/she has set up their login credentials. If it returns false, you may opt to void or deny access to that feature.

Facebook Plugin

For more advanced tasks related to Facebook, you should use the Facebook Graph API. To begin using it, you must first create a developer account at developers.facebook.com. Please see the Facebook Portal Setup guide for assistance with this process — it requires some very precise information and it's imporant to follow every step carefully.

This section and all following sections assume that you have created your Facebook Native App using the aforementioned guide.

Requiring the Plugin

As with all Corona plugins, you must include the Facebook plugin within the plugins table of build.settings:

settings = {

    plugins =
    {
        ["facebook"] =
        {
            publisherId = "com.coronalabs"
        },
    },
}

Then, you must require() the plugin to use the related functions:

local facebook = require( "facebook" )

Login Considerations

Before the Facebook Graph API can be used, the app must successfully log in to Facebook. Then, it must gather the required authentication information ("authToken") and the specific permissions required by the app. This process varies depending on the presence of the native Facebook app.

  • If the mobile device has the native Facebook app installed, your app will launch it and ask for the necessary permissions. When this happens, your app is temporarily suspended and placed into the background while the native Facebook app runs. When complete (the user has either granted permission or has cancelled), the Facebook app will try to restore your app and put it in the foreground, bringing with it the information about your permission request.

  • If the mobile device does not have the native Facebook app installed, it will use Facebook's website to log in through. This happens through a web view, so your app is never actually suspended to the background. In general, the web-based login method is very reliable, but you (the developer) cannot control if your app's user does or doesn't have the native Facebook app installed. Therefore, you must support both methods.

iOS Requirements

If your app is for iOS, you must include the following code in build.settings to ensure that the native Facebook app functions properly:

settings = {

    iphone =
    {
        plist =
        {
            UIApplicationExitsOnSuspend = false,
            FacebookAppID = "XXXXXXXXXX",  --replace XXXXXXXXXX with your Facebook App ID
            CFBundleURLTypes =
            {
                { CFBundleURLSchemes = { "fbXXXXXXXXXX", } }  --replace XXXXXXXXXX with your Facebook App ID
            }
        }
    }
}

There are three critical parts which must be specified:

  • UIApplicationExitsOnSuspend — to ensure that Facebook can resume your app properly, you must include UIApplicationExitsOnSuspend = false. If you've set this parameter to true for some other reason, you must revert it to false (default).

  • FacebookAppID — set this key to FacebookAppID = "XXXXXXXXXX" and replace XXXXXXXXXX with your unique Facebook App ID.

  • CFBundleURLTypes — the CFBundleURLTypes table must be declared exactly as shown and it must include a table named CFBundleURLSchemes. Inside this, include your Facebook App ID and prefix it with fb. Thus, if your App ID is 1234567890, you should specify: "fb1234567890".

Android Requirements

On Android, Facebook uses your app Package Name, for example com.yoursite.yourapp. To ensure that the native Facebook app functions properly, you must provide Facebook's portal with two important pieces of information — these include the Class Name of com.ansca.corona.CoronaActivity and the Key Hash gathered from the keystore you built your app with. These are discussed in the Facebook Portal Setup guide.

Android also requires Internet permission for the app, so include it in build.settings:

settings = {

    android =
    {
        usesPermissions =
        {
            "android.permission.INTERNET",
        },
    },
}

Logging In/Out

Facebook now requires a two-pass login process. The first pass allows you to request basic read-only permissions. Once authenticated with access to basic permissions, if you need any publishable resources or extended permissions, you must log in a second time and request these extended permissions.

To log the user into Facebook, use the facebook.login() call. First, create a local variable equal to the same Facebook App ID that you specified in build.settings. Pass this variable as the first parameter to facebook.login(). Next, specify an event listener function to respond to Facebook requests, including the login request — this function will be the only place where Facebook results are sent. Finally pass a table of permissions as a comma-delimited list of string values:

local fbAppID = "XXXXXXXXXX"  --replace with your Facebook App ID
facebook.login( fbAppID, facebookListener, { "user_friends", "email" } )

Then, to request extended permissions (after a successful initial login), call facebook.login() again:

facebook.login( fbAppID, facebookListener, { "publish_actions", "user_birthday" } )

To log out and disconnect the app from Facebook's services, simply call:

facebook.logout()

This function will end the app's session with Facebook, forcing another call to facebook.login() to log the user in again. This does not log the device's user out of Facebook entirely. It also does not log them out of the native Facebook app.

Facebook Listener

All Facebook requests will call the listener function you passed on facebook.login():

local json = require( "json" )

local function listener( event )

    print( "event.name:" .. event.name )  --"fbconnect"
    print( "isError: " .. tostring( event.isError ) )
    print( "didComplete: " .. tostring( event.didComplete ) )
    print( "event.type:" .. event.type )  --"session", "request", or "dialog"
    --"session" events cover various login/logout events
    --"request" events handle calls to various Graph API calls
    --"dialog" events are standard popup boxes that can be displayed

    if ( "session" == event.type ) then
        --options are "login", "loginFailed", "loginCancelled", or "logout"
        if ( "login" == event.phase ) then
            local access_token = event.token
            --code for tasks following a successful login
        end

    elseif ( "request" == event.type ) then
        print("facebook request")
        if ( not event.isError ) then
            local response = json.decode( event.response )
            --process response data here
        end

    elseif ( "dialog" == event.type ) then
        print( "dialog", event.response )
        --handle dialog results here
    end
end

Making Requests

To make different Graph API requests, use the facebook.request() call.

facebook.request( path [, httpMethod, params ] )

There only required parameter is path which is based on the Facebook Graph API path. This will typically be the REST object that you want to access, for example:

facebook.request( "me/feed" )

This command will retrieve the latest posts from the user's account feed. By default, this call makes HTTP GET requests to Facebook. If you wish to send things to Facebook, you must use a HTTP POST request.

Some Graph API calls require parameters to be passed to facebook.request(). This is done via the optional params table, for instance:

facebook.request( "me/feed", "POST", { message="Hello Facebook" } )

To upload a photo to Facebook, the params table requires the image details — base directory, file name, and type:

local attachment = {
    message = "Corona Icon file",
    source = {
        baseDir=system.DocumentsDirectory, 
        filename="coronaIcon.png",
        type="image"
    }
}

facebook.request( "me/photos", "POST", attachment )

When these requests complete, your Facebook listener function will be called with an event.type of "request". Facebook generally returns your data as a JSON-encoded table of data. To convert this JSON table into a Lua table that you can use, call json.decode() and remember to include the json library as indicated:

local json = require( "json" )

local data = json.decode( event.response )

To learn more about which requests, parameters, and data the Facebook Graph API provides, please see the Facebook Graph API documentation.

Using Dialogs

Facebook requires that some tasks be done through dialogs they control. To use a dialog, call the facebook.showDialog() function:

facebook.showDialog( action [, params, onComplete] )

Two common action settings include "feed" and "apprequests". For example, if you want to challenge somebody to a match in a multiplayer game, use the "apprequests" dialog:

facebook.showDialog( "apprequests", { message="Download this game and challenge me!" } )

The optional params is a table of key/value pairs that gets passed to the Facebook API call. The keys that you pass correspond to specific options which are available for the dialog. See the Facebook Dialog API documentation for details.

Finally, if the Facebook app dialog supports a callback function to return data, you can specify an optional event listener as the onComplete parameter. Two action settings which support this are "places" and "friends".

Published Installs

While not part of the Graph API, Published Installs is a way for apps to participate in Facebook's mobile ad campaign which can report (to Facebook) that the app has been installed. This process is simple and there is no callback information and no need to call facebook.login()

facebook.publishInstall( "XXXXXXXXXX" )  --replace XXXXXXXXXX with your Facebook App ID

For iOS, this process does require a few additions to build.settings:

settings = {

    iphone =
    {
        plist =
        {
            UIApplicationExitsOnSuspend = false,
            FacebookAppID = "XXXXXXXXXX",  --replace XXXXXXXXXX with your Facebook App ID
            CFBundleURLTypes =
            {
                { CFBundleURLSchemes = { "fbXXXXXXXXXX", } }  --replace XXXXXXXXXX with your Facebook App ID
            },

            ["URL types"] =
            {
                item =
                {
                    ["URL Schemes"] = { ["Item 0"] = "fbXXXXXXXXXX" },  --replace XXXXXXXXXX with your Facebook App ID
                },
            },
        }
    }
}