Facebook Connect with Rails (using Omniauth and Devise) [Update]

This is an update to my last post about Facebook Connect with a Rails app. At the time I was using facebooker plugin (yeah, a plugin, not a gem), which has been discontinued for the longest time, and thus wouldn’t work with current Facebook connect.

Since then, I’ve used omniauth, omniauth-facebook, and devise gems to implement Facebook connect with a few Rails app I have been toying with. So, this is kind of an update to my last post about integrating Facebook Connect with a Rails app.

1. First, you need the following gems in your Gemfile.

gem 'devise'
gem 'omniauth'
gem 'omniauth-facebook'
gem 'oauth2'

Make sure you install them by running “bundle install” command.

2. Next configure devise gem.

rails generate devise:install

3. Apply devise to a model. 99.9% of time, this would be the User model.

rails generate devise User

4. Next, generate authentication model with the following columns. Token column is extra, if you want to save an access token.

rails g model Authentication user_id:integer provider:string uid:string token:string

5. Configure omniauth by modifying config/initializers/omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
  # The following is for facebook
  provider :facebook, [APP ID], [SECRET KEY], {:scope => 'email, read_stream, read_friendlists, friends_likes, friends_status, offline_access'}

  # If you want to also configure for additional login services, they would be configured here.
end

6. After user authenticates with whatever provider you specify, user needs to be redirected to omniauth call, so add the following line in your routes.rb.

match '/auth/:provider/callback' => 'authentications#create'

7. Then in Authentications controller, you figure out whether to create a new user or log the user in, if the user is an existing user. For complete hash, take a look at omniauth-facebook github page.

def create
  auth = request.env["omniauth.auth"]

  # Try to find authentication first
  authentication = Authentication.find_by_provider_and_uid(auth['provider'], auth['uid'])

  if authentication
    # Authentication found, sign the user in.
    flash[:notice] = "Signed in successfully."
    sign_in_and_redirect(:user, authentication.user)
  else
    # Authentication not found, thus a new user.
    user = User.new
    user.apply_omniauth(auth)
    if user.save(:validate => false)
      flash[:notice] = "Account created and signed in successfully."
      sign_in_and_redirect(:user, user)
    else
      flash[:error] = "Error while creating a user account. Please try again."
      redirect_to root_url
    end
  end
end

8. In User model, store essential information with apply_omniauth method.

has_many :authentications, :dependent => :delete_all
def apply_omniauth(auth)
  # In previous omniauth, 'user_info' was used in place of 'raw_info'
  self.email = auth['extra']['raw_info']['email']
  # Again, saving token is optional. If you haven't created the column in authentications table, this will fail
  authentications.build(:provider => auth['provider'], :uid => auth['uid'], :token => auth['credentials']['token'])
end

9. In Authenication model,

belongs_to :user

10. In your view, user clicking on /auth/facebook/ link will be redirected to Facebook to log in.

<%= link_to 'Login with Facebook', '/auth/facebook/' %>

11. This method doesn’t do FB login in a popup. For that, you have to use FB Javascript SDK, and you can use the example here.

Post to Twitter

How to install Ubuntu on Chomebook (CR-48) and put parental control

I have had a couple of first-generation Chromebook (CR-48) for a while. I thought these would be pretty good portable computing devices to give to my kids. However, I wasn’t ready to do so unless there was some sort of parental control. As someone who spends a lot of time online, it’s too rough place for kids to roam around. I have known about their support for dev mode, and I decided to figure out which linux flavor would support CR-48.

First search attempt turned out Ubuntu, and since Ubuntu is known for better UI, I decided to give it a try. I also found out there is an excellent parental control guide on Ubuntu as well.

Install Ubuntu on Chromebook (CR-48)

There is no need to re-invent the wheel. Follow instruction here to put Ubuntu 11.04 on Chromebook (CR-48). It worked out like a charm.

Parental Control on Ubuntu

There is a great guide here, and I couldn’t get the Web Content Control to work. However, timekpr is pretty good. You should at least install that.

For filtering content, ProCon Latte Content Filter Firefox Add-on has been working pretty well.

So far, I have been happy with Ubuntu on CR-48. It’s slow and keypad doesn’t work too well, but I think kids are just happy to have their own laptops. :)

Post to Twitter

How to install KidsRuby on Mac OS X and Ubuntu

I have two kids, and I have been wanting to find ways to introduce my kids to programming. Especially for my son, who has asperger syndrome. I thought programming would be a good way to use his interests in logic and mathematics to good use.

I was so much in joy when I found KidsRuby. It’s an awesome project. I think Ruby is a great first language because of its elegance and object-oriented nature to the core.

Previously I had a hard time installing KidsRuby my Mac OS X, due to qt installation error. I was able to at least get it going by cloning their git repository. I had filed a bug for the qt installation error, and the author responded some time ago, but I hadn’t had time to verify it.

I finally had time to verify it, and it worked like a charm.

I also had converted two first-generation Google Chromebooks to use Ubuntu to give to my kids. And while I was familiar with Fedora, this was my first time using Ubuntu, and as new user, I had to search around the net to install Ruby and to install KidsRuby. I am close to finishing it, and I will describe it here.

Mac OS X

This one is pretty easy. Just download the installer dmg file from here, and follow the instruction. It will take a while, but it would be well worth it. You can find the KidsRuby folder in Application folder.

Ubuntu

Now, this one took a while. If you have Ruby installed already, you are good to go. If not, follow the direction below.

If Ruby isn’t installed

You can simply follow the direction from Ryan Bigg to install Ruby 1.9.3.

If Ruby is already installed

I am not sure which version of Ruby is supported, but this applies to Ruby 1.9.3.

The biggest problem I faced was the problem with ffi gem. I kept getting the following error.

Installing ffi (1.0.10) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/bin/ruby1.9.1 extconf.rb
:29:in `require': no such file to load -- mkmf (LoadError)
	from :29:in `require'
	from extconf.rb:4:in `'

Gem files will remain installed in /usr/share/kidsruby/ffi/ruby/1.9.1/gems/ffi-1.0.10 for inspection.
Results logged to /usr/share/kidsruby/ffi/ruby/1.9.1/gems/ffi-1.0.10/ext/ffi_c/gem_make.out
An error occured while installing ffi (1.0.10), and Bundler cannot continue.
Make sure that `gem install ffi -v '1.0.10'` succeeds before bundling.

After searching the net for a while, I realized that I needed to install “-dev” package as well. Since I am using 1.9.3, I had to install ruby1.9.1-dev.

sudo apt-get install ruby1.9.1-dev

After that you can clone the git repository and install necessary packages.

git clone https://github.com/hybridgroup/kidsruby.git

cd kidsruby

sudo apt-get install libqt4-dev
sudo apt-get install cmake
gem install qtbindings
bundle install

The bundle install part will take a while.

For the lesson part, I had a surprising result – my son totally lost interest very quickly, but my daughter was more into it. :)

KidsRuby on Ubuntu

Post to Twitter

Never never give up on your life

When I first read TechCrunch’s article on Diaspora co-founder Ilya Zhitomirskiy’s death, I didn’t think much of it except that it didn’t mention anything about the cause of the death. It usually means only thing, and my suspicion was confirmed by hacker news thread.

http://news.ycombinator.com/item?id=3231531

What I particularly noticed about the thread was discussion of failure and stress of founding a startup and other suicides by very smart folks. It also reminded me of earlier tragic passing of a co-founder of a Y-Combinator-funded company and the article I read on WIRED magazine about two AI scientists committing suicides almost in identical ways.

I would never know why these guys did what they did. But for me, I have one thing that would prevent me from thinking about it. It’s my kids and my family to an extent. It’s a double-edged sword. On one side, it’s the reason for not being able to take huge risk, but on the other side, it’s the reason for my sanity no matter how shitty my life is at any given moment (and my life right now isn’t all that spectacular).

Also, we should also keep things in perspective. In grand scheme of this universe, we are just small part of green/blue spec called Earth. You shouldn’t care about and be afraid of failures/rejections. Who cares? People will forget and move on. I think it’s courageous and commendable to just try. Regardless of outcome, having tried something sets you ahead of many others.

Just remember the following quotes.

“Regret for the things we did can be tempered by time; it is regret for the things we did not do that is inconsolable.”

Also, especially this one.

“It is not the critic who counts; not the man who points out how the strong man stumbles, or where the doer of deeds could have done them better. The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood; who strives valiantly; who errs, who comes short again and again, because there is no effort without error and shortcoming; but who does actually strive to do the deeds; who knows great enthusiasms, the great devotions; who spends himself in a worthy cause; who at the best knows in the end the triumph of high achievement, and who at the worst, if he fails, at least fails while daring greatly, so that his place shall never be with those cold and timid souls who neither know victory nor defeat.”

Post to Twitter

Fresh installation of Ruby, Rails, Git, RubyGems, and Postgresql 8.x

Most people need to do this only when they get a new system. I had to go through this to help out a potential brogrammer, and it would have been much easier if I pointed him to one place where he could just following direction. Instruction here applies to Mac OS X 10.6.x.

For Windows users, use the convenient installer done by guys at EngineYard from here (http://railsinstaller.org/) to install Ruby, Rails, etc., and installer from Postgres from here (http://www.postgresql.org/download/windows/) to install Postgresql.

1. Install Xcode

Xcode is included in the Mac OS X install disc. You can install from the DVD or you can down load it from here,
http://developer.apple.com/xcode/. If you already have xcode installed, you are good to go.

2. Install Git

Download and install git if you don’t have one already. Do the following and see if returns a version.

git --version

Best place is to go here (http://git-scm.com/), and download and install the latest stable release.

3. Install RVM and Ruby

RVM lets you manage set of gems for Ruby/Rails version combination. This is the best way to install Ruby and Rails. Follow the link below and install RVM and Ruby version 1.9.2 (which is latest, stable version as of this time).

curl -L get.rvm.io | bash -s stable --ruby

3.1. Then, update the .bash_profile (or whatever shell profile or rc file you need)

echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile

3.2. Reload the shell.

source ~/.bash_profile

3.3. Test to see if installation was successful.

rvm list known

3.4. Install Ruby 1.9.2 (or 1.9.3)

rvm install 1.9.2

3.5. It’s probably a good to set 1.9.2 as default as well.

rvm use 1.9.2 --default

4. Install RubyGems if not already installed

Doing the following command in terminal and see if it returns version number.

gem -v

If it doesn’t return a version number, follow the steps below to install RubyGems.

4.1 Download the latest stable version from here (http://rubygems.org/pages/download)

4.2 Unzip and Install

tar xzvf rubygems-1.X.Y.tgz
cd rubygems-1.X.Y
sudo ruby setup.rb

5. Configure RVM gemset

Now, you have to actually make a choice whether you want to install the latest version 3.1 or the one before 3.0.x. If you just do gem install rails, it will install 3.1. I am sticking with 3.0.10 for a little longer, since that’s what I am used to. But, if you are starting new, you should just install 3.1. When you search for code examples online, make sure it’s for 3.1, since 3.1 is quite different from 3.0.x.
rvm gemset create rails31

Also set default gemset.

rvm use 1.9.2@rails31 --default

6. Install Rails

Depending on what you decided above,

gem install rails -v 3.1.0

7. Install Postgresql 8.x

I’ve used MySQL mostly before, but after Oracle’s purchase of MySQL and since I deploy most of my apps on Heroku, which only supports Postgresql, I have been using Postgresql for quite sometime. For typical Rails app, it shouldn’t matter whether you use MySQL or Postgresql. You need to be careful when you need to write raw SQL statement. Postgresql is known to be more strict with the syntax.

Latest Postgresql is 9.x, but I believe pg gem only supports up to 8.x. Better stick with safe version.  Follow the link below to download and install Postgresql 8.x. Remember the admin username and password.

http://www.enterprisedb.com/products-services-training/pgdownload

pg gem will be installed when you create a Rails app with

rails new [APP NAME] -d postgresql

and install gems with

bundle install

8. Configure Postgresql for Rails

The most you have to configure is to create a user and password for each app.

8.1 Login as admin (whatever admin username you picked when you installed the Postgresql)

psql -U admin

8.2 Create a username and password for your app.

create role [USERNAME] with createdb login password '[PASSWORD]';

You would use the username and password you just created in /config/database.yml file in your Rails app.

Post to Twitter

(org.mongodb.mogod) Exited with exit code: 100

For some reason, I couldn’t run mongo shell and the console was overrun by the same error message like the following.

8/1/11 6:49:15 PM com.apple.launchd[1] (org.mongodb.mongod) Throttling respawn: Will start in 10 seconds
8/1/11 6:49:25 PM com.apple.launchd[1] (org.mongodb.mongod[394]) Exited with exit code: 100
8/1/11 6:49:15 PM com.apple.launchd[1] (org.mongodb.mongod) Throttling respawn: Will start in 10 seconds
8/1/11 6:49:25 PM com.apple.launchd[1] (org.mongodb.mongod[394]) Exited with exit code: 100

And searching on Google didn’t turn up any interesting results.

IT PAYS TO LOOK AT YOUR LOG FILE! Well, this shouldn’t be new, but it somehow skipped my mind until I saw the config file.

In the log file was the following helpful error message.

**************
old lock file: /usr/local/mongodb_data/mongod.lock.  probably means unclean shutdown
recommend removing file and running --repair
see: http://dochub.mongodb.org/core/repair for more information
*************

Mon Aug  1 18:49:35 [initandlisten] exception in initAndListen std::exception: old lock file, terminatingMon Aug  1 18:49:35 dbexit:
Mon Aug  1 18:49:35 [initandlisten] shutdown: going to close listening sockets...
Mon Aug  1 18:49:35 [initandlisten] shutdown: going to flush diaglog...
Mon Aug  1 18:49:35 [initandlisten] shutdown: going to close sockets...
Mon Aug  1 18:49:35 [initandlisten] shutdown: waiting for fs preallocator...
Mon Aug  1 18:49:35 [initandlisten] shutdown: closing all files...
Mon Aug  1 18:49:35 closeAllFiles() finished
Mon Aug  1 18:49:35 dbexit: really exiting now
Well, after deleting the lock file, everything was back to normal.

When in doubt, always look in your log file!

Post to Twitter

Relevance in current Internet

I just finished reading TechCrunch article, How Facebook Can Put Google Out of Business. This also reminded me of Paul Adam’s articles, The Real Life Social Network and How Your Customers’ Social Circles Influence What They Buy, What They Do and Where They Go. And also this good analogy of Facebook, Google and other hot startups.

I was also asked a lot of questions about problem of current social media and how I could make it better as part of interview questions. One common answer I provide is the relevance. How important are these news, status updates, tweets, etc. to me? I agree that the biggest difference between Facebook and Google is the core of each company – people (social) or links (web pages).

Many companies are trying to figure out who you are as a person. For example, another favorite startup of mine, Hunch, is trying to figure out who you are and what you would like based on what you already like. Netflix tries to figure out what movies you might like based on your ratings of movies. Amazon has been doing it for a while with features like “you might also like…” Facebook is obviously in good position because of the social interaction data they have – what you shared, who you have interacted with, what you liked, etc. in addition to social graph. Twitter can also certainly figure out by analyzing followers, tweets and especially retweets, but right now I feel that noise-to-signal ratio on Twitter is too high. You control tweet relevance by carefully choosing who you follow.

We are bound to create more data. The amount of data we generate will never decrease. In the sea of data, it would be harder and harder to find information that is relevant to you, but to others. In this sense, Facebook is definitely sitting on a gold mine. It’s kind of creepy, but the more interactions you have on Facebook, the more Facebook knows you, and it provides good targeting data to advertisers. Can Google build significant social product? Nothing is impossible, but I think it would be very hard. Facebook is just too big, and I just don’t see why I would use similar feature on another platform. Once you have your social network established on one platform, it is extremely hard to create the similar network on a different platform. In social network, the winner takes all, unless the winner screws up big time. It could happen (as has happened a couple of times already with Friendster and MySpace).

We are living in an interesting time, indeed.

Post to Twitter

Lean Startup in Education (Hacking for Education)

Today I have had the most productive conversation with my wife (which is shame because I think she has a lot of good insights and look at things from different view points). It was inside the car, while we were driving to Lawrence Hall of Science, which is an awesome place all around.

I had to leave my most current job abruptly, and knowing the reasons behind it, she asked me what’s the most important element angel investors look before making an investment. It was an easy question to answer – the team, of course. And she wholeheartedly agreed. She said she experienced exactly the same at her Korean school, where she teaches grade school kids, and at Korean American Community Center, where she worked before working at the Korean school.

The Korean school she teaches at is part of a church (I am an atheist, but I welcome all religions), and thus their curriculum is not directed or regulated by school district. She said she and a few other teachers like to try new ways of teaching kids. Their attitudes were just like those of tech startup founders. Failure is okay, since you will learn more from failures and apply it to the next new idea. However, she said there were other teachers who are very resistant to trying new things even if they are not the ones implementing or preparing the experiment. Not only do they waste time, they also put out the passion brought on my good teachers. So, she understood how important the team is. Not everyone in the team needs to be super smart, but it’s important for the team to be open to experiments, not be afraid of failures and support each other.

She said she saw the same thing at the Korean American Community Service. She worked there as an office manager until our first child was born. The community center reached the peak while she was there, because she said everyone was open to trying new things – services or classes or whatever – to serve the community better. And most of all, they had the full support from the head of the community center. She also said amazing thing about leadership. Good leadership is not about leading, but creating an environment for team members to innovate. You shouldn’t try to make everyone follow your views, thoughts or directions, but instead give team members freedom to experiment, learn from successes/failures and move  forward. I was like DANG! That’s the most insightful thing I heard from my wife (again, I should have more conversations with her) . :)

I told her that’s the exact operating principal for tech startups these days. I couldn’t believe we were in such unison! And it got me thinking about our education system.  Many people are concerned about our failing education system, and WE HAD THE ANSWER ALL ALONG! Apply “Lean Startup” principal to our education. Encourage teachers to take 20% of their time to innovate. It’s not possible without school district’s support, but if there is, it’s totally doable. And have Lighting Talk or Lesson Learned sessions with other teachers so that they could learn from others’ successes or failures. And pivot if an idea didn’t work out. Or perhaps we need an national website for teachers to share their experiments and lessons learned from them. I truly believe this HACKING FOR EDUCATION will save us, and put our great nation again in leading position.

Post to Twitter

Silicon Valley Bubble

I went back home to the East Coast, Washington DC suburb, this past holiday season. I also went up to see my friends and cousins in NJ and NY. Having the first meaningful conversation with my friends and relatives in about two years made me realize one thing about Silicon Valley.

We (those of us living in the SF Bay Area) are living in a bubble. I am not talking about startup/options/hype kind of bubble, but a tech bubble. I was the one most knowledgeable about up-to-date information of facebook and its eco-system with apps and social games, twitter, google, etc. None of my friends and relatives seem to know nor even care about such information.

It’s just amazing and unbelievable when you think about such high concentration of technical knowledge, talent and money in one geographical area.

Post to Twitter