facebook-authSome things with Facebook are easy while others are more challenging. Getting a list of Facebook friends has been, traditionally, one of the more challenging tasks: you need to use facebook.request() to ask for the "me/friends" object, convert the huge JSON object into a Lua table, and then load that into a newTableView() widget — including downloading each friend’s avatar and inserting it. Then you need to handle the potential selection of several friends and work the data back into your app where you can use it.

Fortunately, Corona SDK offers an easier way to select a set of Facebook friends using the facebook.showDialog() API.

Initial Setup

With any app that uses Facebook, you have to set it up so it will communicate with Facebook. This, in itself, is not a trivial process — see the Implementing Facebook Guide for details.

As of April 30, 2014, Facebook only allows this dialog to return a list of friends who have your app installed and have agreed to the user_friends permission. Please see User IDs and Friends on the Facebook Developer Portal for more information.

As of Corona SDK Build 2165 (2014.2165), Facebook for iOS was removed from the core and is now implemented via a plugin. If you’re using this build or later and you’re targeting iOS, you must include the following in the build.settings file.

settings = {

   plugins =
   {
      ["facebook"] =
      {
         publisherId = "com.coronalabs",
         supportedPlatforms = { iphone=true, ["iphone-sim"]=true }
      },
   },
}

Similarly, as of Corona SDK Build 2431 (2014.2431), Facebook for Android was removed from the core and is now implemented via a plugin. If you’re using this build or later and you’re targeting Android, you must include the following in the build.settings file. Note that the supportedPlatforms line has been removed in this case for cross-platform compatibility.

settings = {

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

On iOS, you must include (at the minimum) the following in your build.settings plist section:

FacebookAppID = "XXXXXXXXXX",  -- Replace XXXXXXXXXX with your Facebook App ID
CFBundleURLTypes = {
   {  -- This set of braces is important!
      CFBundleURLSchemes = { "fbXXXXXXXXXX", }
   }
},

In addition, make sure that you build with a provisioning profile that matches the com.yoursite.yourapp entry which you added on the Facebook Developer Portal.

On Android, you must build your app with the Keystore and Alias of the keystore which you used to build the keyhash from the developer portal.

App Code

Next, you should set up the basic Facebook login processor. This includes a require of the Facebook library, a listener to handle the login process, and logging in to Facebook.

local facebook = require( "facebook" )
-- Listener for "fbconnect" events
local function listener( event )
   if ( "session" == event.type ) then
      -- Upon successful login, request list of friends
      if ( "login" == event.phase ) then
         -- Show the friends picker
         facebook.showDialog( "friends", onComplete )
      end
   elseif ( "dialog" == event.type ) then
      print( event.response )
   end
end
local FBAppID = "XXXXXXXXXXX"  -- Facebook App ID from build.settings, without the "fb" prefix.
facebook.login( FBAppID, listener, { "publish_actions" } )

Now the Facebook system is initialized. As for the “Friends” dialog itself, it requires a callback listener which gathers the list of friends returned:

local function onComplete( event )
   print( "event.name:", event.name )
   print( "event.type:", event.type )

   if ( event.data ) then
      -- event.data is a table of friends returned.
      -- event.data[1] will be the first friend returned.
      -- Each friend will have a list of fields returned like:
      ----- event.data[1].firstName
      ----- event.data[1].fullName
      ----- event.data[1].lastName
      ----- event.data[1].id
   end
end

Next, set up a “show dialog” function and a basic button to trigger it:

local widget = require( "widget" )

local function showDialog( event )
   if ( event.phase == "ended" ) then
      facebook.showDialog( "friends", onComplete )
   end
   return true
end

local button = widget.newButton{
   label = "Pick Friends",
   onEvent = showDialog,
}
button.x = display.contentCenterX
button.y = display.contentCenterY

In Summary

With this code in place, you can easily pick a list of friends to social network with. What you do from there is up to your imagination!

  1. Thanks for this great tutorial. Quick question. Since this is not using the socials plugin we should not have the following in our build.settings file in this case right? Would it create a problem to have the plugin in there and rely on both the plugin and the facebook.showDialog() API? Thanks for your clarification.

    –key is the name passed to Lua’s ‘require()’
    [“CoronaProvider.native.popup.social”] =
    {
    –required
    publisherId = “com.coronalabs”,
    },

  2. Note: above in the “important” section, it says to specify the facebook info in the “plugins” section of build.settings. But then in the comments, Kerem & Rob say that this is not required…..can we fix the tutorial so people who don’t read the comments dont assume a dependency that doesn’t exist? I’m not sure I know the difference between this method and the “socials” plugin….can someone link to a document that explains the pro’s and conn’s of each approach?

    • As the box around the plugin section says, we made a change as of build 2165 to move facebook to a plugin instead of having it in the core. This was a vendor required change.

      I cannot edit comments, so we expect people to see the big colored box and understand it’s an update.

      • oh…so you are saying that Kerem’s comment (1st above) occurred BEFORE that change (pulling Facebook out of core) so now, IT IS REQUIRED to have it in the build settings…

        Ok, now that makes sense…

        Since this was “a vendor required” change, (I’m assuming you mean vendor=Facebook)….is it safe to assume that under-the-hood, Corona is using the native Facebook SDK and our use of these methods is in compliance with Facebook’s new (link below) rules??

        • The social plugin uses the operating system’s social network support. The facebook.* API calls let you do things directly with Facebook. The social plugin has always been a plugin. Facebook.* was in the core, but we moved it to a plugin. So for the social plugin, you have always needed the build.settings code. For the facebook.* API you used to not need it, but now you do. They are different plugins. And should your app use both (and I’m not real sure why you would), then you need to include both blocks of plugin code.

          Facebook’s use rules are constantly changing. We work to try and keep our facebook.* API calls compatible with the latest rules that Facebook may be enforcing. We try to stay ahead of their quarterly breaking changes.

  3. Assuming what’s described above the new “preferred” way to do facebook “friends” functionality??
    Does this technique apply to other Facebook requests?

    In other words, should we follow the pattern shown in Samples>Networking–>Facebook sample app, or disregard it and use only this tutorial??

    If that sample app is still valid/useful, will this code pattern get added to the latest sample app?
    It doesn’t seem to be there currently….

    • There are only a few “dialogs” that are supported. I would think if Facebook offers a dialog to do something, it’s probably the best way to do it. The Open Graph API system will still be there for more customized things.

      The sample app is still a valid way to do thing because you may want a customized friends list beyond what this provides.

  4. How if i want to post to friend’s wall??
    Here’s my code but it’s not work.
    Please help me. Thanks.

    local function onComplete( event )
    if ( event.data ) then
    for k, v in pairs( event.data ) do
    local attachment = {
    name = v.firstName..”, you got post”,
    link = “http://www.coronalabs.com/links/forum”,
    caption = “myapps”,
    description = “yee”
    }
    facebook.request( v.id ..”/feed”, “POST”, attachment )
    end
    end
    end

      • Thanks Mr. Rob for answering..
        how if I post to my wall and tag a friend?? but i have difficulty to get friend’s id.
        I’ve try this code but no data received. I try to show the id using display.newText

        local function onComplete( event )
        if ( event.data ) then
        for k, v in pairs( event.data ) do
        TT.text = v.id
        end
        end
        end

        facebook.showDialog( “friends”, onComplete )

  5. Hi Mr. Rob,
    I install the sample code “Facebook” in corona sdk.
    Change the fb ID from XXXXXXXXXX to my fb appID in build.setting and main.lua.
    However, after I install it on my ipad and it doesn’t work.
    Does the facebook api really work when we write
    plugins =
    {
    [“facebook”] =
    {
    publisherId = “com.coronalabs”,
    supportedPlatforms = { iphone=true, [“iphone-sim”]=true },
    },
    },
    ???
    It seems that after compiling code, the facebook lib doesn’t be included.
    Could you help me?
    Thanks.

  6. What is the best way to test this? the fb libraries don’t work in the simulator. Is the only way to build then move the ipa to the device then run etc? Thanks.

  7. I just went back to test this feature (which I had working months ago) and suddenly, my friend-list dialog comes up completely empty…all my code is running correctly and callbacks are getting called, just no people in the list. I’ve even gone and deleted the app on my facebook account (user side, not dev side) to force a re-grant of permissions and I get nothing…..

    All tips appreciated….
    Thx
    D

    • Yea, Facebook likes to do that. Their service is such a moving target, really the best thing you can do is follow the Facebook topics in the forums and try to stay on top of the changes the community discovers and adapt to those changes.

      Our tutorials are not designed to be drop-in code but to teach you how to do things. We fully expect that you will have to adapt them to your specific needs and in the case of 3rd party features adapt them as the 3rd party changes.

      In the mean time I’ll go back and see if I can figure out the changes needed and update the tutorial accordingly.

      Rob

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>