Skip to content
This repository

Here are a few tips for using Koala with your Rails application. It seems to be a popular topic on the Koala Google Group, so hopefully this helps a little bit.

FYI: Koala works with both Rails 2 and Rails 3, as well both Ruby 1.8 and Ruby 1.9.

Configuration file

If you’re using the OAuth class (or even the RealtimeUpdates class) it gets a little redundant always passing in your Facebook application ID and secret to create new instances of the OAuth class. To fix that, we’ll create a configuration file with your Facebook application ID and secret and extend Koala to always use those given values.

First we’ll put a YAML file into the config directory:

# config/facebook.yml
development:
  app_id: YOUR APP ID
  secret_key: YOUR SECRET
test:
  ...
production:
  ...

Now you can add a ruby file to read the configuration file and extend Koala when Rails is initialized in the config/initializers directory:

# config/initializers/koala.rb
# Monkey-patch in Facebook config so Koala knows to 
# automatically use Facebook settings from here if none are given

module Facebook
  CONFIG = YAML.load_file(Rails.root.join("config/facebook.yml"))[Rails.env]
  APP_ID = CONFIG['app_id']
  SECRET = CONFIG['secret_key']
end

Koala::Facebook::OAuth.class_eval do
  def initialize_with_default_settings(*args)
    case args.size
      when 0, 1
        raise "application id and/or secret are not specified in the config" unless Facebook::APP_ID && Facebook::SECRET
        initialize_without_default_settings(Facebook::APP_ID.to_s, Facebook::SECRET.to_s, args.first)
      when 2, 3
        initialize_without_default_settings(*args) 
    end
  end 

  alias_method_chain :initialize, :default_settings 
end

This overrides OAuth#initialize to take any number of arguments. If OAuth.new gets zero or one parameter, we’ll use our configuration file’s values, otherwise we’ll initialize the OAuth object using the old initializer.

In the case that you want to store the app id and the key in your environment variables, you can use the following initializer code instead, that will do the job.
Remember to add the following keys to environment: FB_APP_ID={your app id}, FB_SECRET_KEY={your secret}

# config/initializers/koala.rb
# Simple approach
Koala::Facebook::OAuth.class_eval do
  def initialize_with_default_settings(*args)
    raise "application id and/or secret are not specified in the envrionment" unless ENV['FB_APP_ID'] && ENV['FB_SECRET_KEY']
    initialize_without_default_settings(ENV['FB_APP_ID'].to_s, ENV['FB_SECRET_KEY'].to_s, args.first)
  end 

  alias_method_chain :initialize, :default_settings 
end

Now creating an OAuth instance is as easy as Koala::Facebook::OAuth.new or Koala::Facebook::OAuth.new(oauth_callback_url).

Authentication

Facebook Connect website

Javascript-based Authentication

Koala’s OAuth class allows easy verification and parsing of the cookies Facebook passes to your application, whether it be a website or Facebook iframe application. As a side note, make sure you’re using the new Facebook JavaScript SDK since the cookie format differs from the older Facebook Connect scripts.

One way to get the cookie data is to setup a before_filter and assign a local variable to store the information:

# app/controller/foo_controller.rb
before_filter :parse_facebook_cookies

def parse_facebook_cookies
  @facebook_cookies ||= Koala::Facebook::OAuth.new(YOUR_APP_ID, YOUR_SECRET).get_user_info_from_cookie(cookies)

  # If you've setup a configuration file as shown above then you can just do
  # @facebook_cookies ||= Koala::Facebook::OAuth.new.get_user_info_from_cookie(cookies)
end

def index
  ...
  @access_token = @facebook_cookies["access_token"]
  @graph = Koala::Facebook::GraphAPI.new(@access_token)
  ...
end

Of course you can add a callback_url when creating the OAuth object, depending on how you’re handling authentication.

If you won’t necessarily need the data from the Facebook cookies on every request, a method in ApplicationController is probably good enough:

# app/controllers/application_controller.rb
def facebook_cookies
    @facebook_cookies ||= Koala::Facebook::OAuth.new(YOUR_APP_ID, YOUR_SECRET).get_user_info_from_cookie(cookies)
end

# app/controllers/foo_controller.rb
def index
  ...
  @access_token = facebook_cookies['access_token']
  @graph = Koala::Facebook::GraphAPI.new(@access_token)
  ...
end

Authentication via redirects


Note: I’ve never actually implemented Facebook authorization using redirects, but this is what I’ve gathered from the Facebook documentaiton. Let us know if this example actually doesn’t work! – Chris

OAuth supports an authentication flow based on redirects, which is outlined on the official Facebook developers site

To authorize a Facebook user present them with a link to the Facebook authentication page. With Koala this might look like:

<%# app/views/welcome.html.erb %>
...
  <%= link_to 'Login', Koala::Facebook::OAuth.new.url_for_oauth_code(:callback => oauth_redirect_url) %>
...

Where oauth_redirect_url is the URL to an action which will handle the rest of the authentication flow.

Assuming oauth_redirect_url points to the OAuthController#redirect action, you can finish off authentication with the following bit of code:

# app/controllers/oauth_controller
def redirect
  session[:access_token] = Koala::Facebook::OAuth.new(oauth_redirect_url).get_access_token(params[:code]) if params[:code]

  redirect_to session[:access_token] ? success_path : failure_path
end

This will store the access_token string in session[:access_token]. Obviously, you can store this value whatever way seems fit given your application/

IFrame Applications on Facebook.com

Using Koala with an iframe application is very similar to using it with an external Facebook Connect application. You can use the Javascript-based authentication methods to authenticate the user and start using the Graph or REST API; Facebook also provides parameters on tab load, which you could associate with the user as well.

Storing Facebook User IDs

As you may or may not be aware, Facebook UIDs are so large that they should be stored in most databases as big ints rather than plain ints. Therefore, if you wish to store a Facebook UID in your database, your migration should be of the form:

add_column :users, :facebook_id, :bigint
Something went wrong with that request. Please try again.