Rails is developing omniauth-facebook. return false
I spent the last day trying to fix this issue and it drove me crazy.
I had a facebook login last night that was working on my site and pulling basic user information. My problems started when I added :scope => 'user_birthday'
in config/initializers/omniauth.rb
, which now looks like
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, "APP_ID", "APP_SECRET", :scope => 'user_birthday'
end
For reference, I removed the line config.omniauth :facebook, "APP_ID", "APP_SECRET"
fromconfig/initializers/devise.rb
I spent hours trying to get this to work but in the end had to give up. Then this morning I ran again and it worked. Joyfully, I tried to add another parameter in :scope
, but now it's all broken again. I can get it to work if I delete :scope
, but when I put it back in, it fails every time (even if it's just :scope => 'user_birthday'
like I had my first lesson this morning).
To find the problem, I entered the debug code in omniauth_callbacks_controller.rb
and now it looks like this:
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
# You need to implement the method below in your model (e.g. app/models/user.rb)
@user = User.from_omniauth(request.env["omniauth.auth"])
puts "start before persist debug"
puts @user.birthday
puts @user.persisted?
puts "end before persist debug"
if @user.persisted?
puts "Start persisted debug"
puts request.env["omniauth.auth"]
puts "End debug"
sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
puts "Start unpersisted debug"
puts request.env["omniauth.auth"]
puts "End debug"
redirect_to new_user_registration_url
end
end
end
This debug clearly shows that facebook is returning the information it needs, but the app fails because it .persisted?
returns false and so I am redirected to the new_user_registration page which returns the following: -
NoMethodError in Devise::Registrations#new
Showing /home/action/workspace/cloudapp/app/views/devise/shared/_links.html.erb where line #23 raised:
undefined method `omniauth_authorize_path' for #<#<Class:0x007f3aeffff038>:0x007f3aefffdf08>
I can't figure out for life why it .persisted?
returns false. I am using Nitrous.io for development with Heroku postgresql database. I confirmed that there are no users in the database by running
rails c
User.all
This returns:
User Load (89.4ms) SELECT "users".* FROM "users"
=> #<ActiveRecord::Relation []>
I have a feeling that the problem is models/user.rb
, but I can't figure out how to debug it to see if it finds the user and therefore won't continue, or tries to create it and won't work. Does anyone know an easy way to debug this?
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.name = auth.info.name # assuming the user model has a name
user.birthday = auth.extra.raw_info.birthday
# user.image = auth.info.image # assuming the user model has an image
end
end
I walked around 50 times and was close to giving up.
The only thing I can think of is something that where(provider: auth.provider, uid: auth.uid)
returns something (which shouldn't, because my database is empty). Maybe there is an index that exists somewhere outside my database and what is it looking for?
Please, for my sanity, can anyone help? If you need more information, I will gladly provide it
Edit 1
Just tried the following and it works, which makes me more confusing than ever:
- Delete the app from my facebook account when I test this account.
- Try to login to facebook from the
:scope => 'user_birthday'
left. Facebook lists the permissions requested asyour public profile and birthday
. Accept and submit back to my site that does not match the above (even if the information is definitely sent back). - Please uninstall
:scope => 'user_birthday'
and try to login again using facebook. Access facebook which lists the permissions requested asyour public profile and email address
. Accept and get directed back to the site that is now up and running, and also have the user's birthday that was available and accessible because I had the resolution with facebook from number 2. above.
Now I'm completely at a loss
source to share
I had the same problem and answered above and I put "@ user.errors.to_yaml" in my code to see where the error was and I found.
I use "devise" and "omniauth-facebook" too. The default for omniauth-facebook is "email". However, I have included the properties area: "user_about_me, user_status, user_location, user_birthday, user_photos". I need to add "EMAIL" to the volume that I need to use to create a "user". I discovered this when I saw my error: "Email is not empty".
Summary: If you put properties into scope, ALWAYS add "email".
source to share
Facebook doesn't always return email for the user
from facebook devs https://developers.facebook.com/bugs/298946933534016
Some possible reasons:
- Account has no email address
- Account has no verified email address
- No verified email address on account
- The user entered a security checkpoint that required them to verify their email address, and they haven't done so yet.
- Users email address is not available
You will also need extended email permission, even for users who have a valid, verified, accessible email address in the file.
The user entered a security checkpoint that required them to verify their email address, and they have not yet done so User email is not available
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
puts request.env["omniauth.auth"] # check if request.env["omniauth.auth"] is provided an email
if request.env["omniauth.auth"].info.email.present?
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
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
else
redirect_to new_user_registration_url, notice: "Can't sign in to your #{request.env["omniauth.auth"].provider} account. Try to sign up."
end
end
end
source to share