How to Handle Facebook App Uninstalls with RFacebook

Posted on February 20, 2008

I posted the following here—but thought I’d solicit other feedback via blog as well.

As of this writing, the rfacebook plugin does not seem to provide a way to handle uninstalls (easily).

Is there a method I’m not aware of? Or does one handle it pretty much how I’ve done below?

In this example, to handle uninstalls in your rails app we will use the post-remove URL of ‘foo.yourapp.com/uninstalled’.

In your application.rb, you probably have something like:

  before_filter :require_facebook_install
  before_filter :require_facebook_login

Change your application.rb to something like:

  before_filter :require_facebook_install, :except => [:uninstalled]
  before_filter :require_facebook_login, :except => [:uninstalled]

  # Before Filter on *only* the 'uninstalled' method
  before_filter :verify_uninstall_signature, :only => [:uninstalled]

  # Note: it's important this method is *above* the 'protected' definition, since it needs to be called directly
  def uninstalled
    @fb_uid = params[:fb_sig_user]
    # From here on it will be app specific -- given the facebook uid, destroy the user, like...
    @user = User.find_by_fb_uid(@fb_uid)
    @user.destroy if @user
    render :nothing => true; return
  end

  protected
   ...

Next, in your ‘protected’ section, add the following method which roughly corresponds to the PHP / pseudocode:

  def verify_uninstall_signature
    signature = ''
    keys = params.keys.sort
    keys.each do |key|
      next if key == 'fb_sig'
      next unless key.include?('fb_sig')
      key_name = key.gsub('fb_sig_', '')
      signature += key_name
      signature += '='
      signature += params[key]
    end
    signature += FACEBOOK['secret']
    calculated_sig = Digest::MD5.hexdigest(signature)
    #logger.info "\nUNINSTALL :: Signature (fb_sig param from facebook) :: #{params[:fb_sig]}" 
    #logger.info "\nUNINSTALL :: Signature String (pre-hash) :: #{signature}" 
    #logger.info "\nUNINSTALL :: MD5 Hashed Sig :: #{calculated_sig}" 
    if calculated_sig != params[:fb_sig]
      #logger.warn "\n\nUNINSTALL :: WARNING :: expected signatures did not match\n\n" 
      return false
    else
      #logger.warn "\n\nUNINSTALL :: SUCCESS!! Signatures matched.\n" 
    end
    return true
  end

This might be handy to add to ‘rfacebook’, but it sounds like the state of that project is in flux.

Also, you might have to add this entry to your config/routes.rb file:

  map.connect 'uninstalled', :controller => 'application', :action => 'uninstalled'

Happy uninstalling! :)