2

I'm using the omniauth-facebook gem with devise. It was working until recently. I also recently upgrated to Rails 5.0.1 from Rails 4, but I'm not sure that's the cause.

I currently have 0 users, and I'm logged into Facebook. But when I try to sign up for my app with Facebook on localhost, I get this error:

NoMethodError in RegistrationsController#facebook
undefined method `provider' for nil:NilClass

Here is my User model. I marked the line that the error highlights.

User.rb

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :omniauthable, :omniauth_providers => [:facebook]


  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user| #ERROR
      @data = auth.info
      user.name = @data.name
      # ...
    end
  end

RegistrationsController

  def facebook
    @user = User.from_omniauth(request.env["omniauth.auth"])
    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

Also, here's my link:

<%= link_to "fb", user_facebook_omniauth_callback_path(:facebook, thing: @thing.id, degree: @degree, :format => :js) %>

The HTML Output:

<a href=\"/auth/facebook/callback.js?thing=2\">fb<\/a>

And the path:

localhost:3000/auth/facebook/callback.js?thing=2

So the problem is that request.env["omniauth.auth"] is nil for some reason. I can't find any traces of similar errors in any documentation.

Anyone encounter this before or have any thoughts?

Joe Morano
  • 1,715
  • 10
  • 50
  • 114

2 Answers2

1

To authenticate via facebook all you need is to put a link from your Site to facebook like this:

www.yoursite.com/auth/facebook

and then set up a route to receive the callback from Facebook with the authentication hash:

#routes.rb      
get 'auth/facebook/callback'  => 'sessions#create_facebook'

Can you specify how the output of this line looks like or why you are passing other information ?:

<%= link_to "fb", user_facebook_omniauth_callback_path(:facebook, thing: @thing.id, degree: @degree, :format => :js) %>

EDIT

auth/facebook/callback is a get request. Facebook sends you the users authentication hash there. Only facebook itself should use that route. When you want to authenticate your link has to be:

localhost:3000/auth/facebook

They way you have it, omniauth is expecting facebook's authentication hash but receives "?thing=2" which results in a failed authentication. Omniauth tries to extract the information from "?thing=2" which is not a hash and when you try to access auth[provider], auth is empty and therefore provider is not defined either which results in :

undefined method `provider' for nil:NilClass
Alexander Luna
  • 5,261
  • 4
  • 30
  • 36
  • I added the HTML output and path of my erb link. The other parameters are just to add additional data to the signup path. Does your solution run on omniauth-facebook? – Joe Morano Apr 15 '17 at 18:41
  • You have a wrong link. The auth/facebook/callback is reserved for facebook. Facebook posts to that route you don't pass info to that route. I updated my answer. – Alexander Luna Apr 15 '17 at 18:51
  • So is it possible to pass additional parameters when creating a new user with Facebook? – Joe Morano Apr 16 '17 at 00:36
  • Yes but inside your omniauth.rb file or as parameters which you can read more about at the facebook-omniauth gem docs. – Alexander Luna Apr 16 '17 at 05:27
0

I had the same issue and solved it by removing :omniauthable from User model

Shimaa Marzouk
  • 429
  • 4
  • 10