Good day. Maybe my problem is nonsense but i have after singup in twitter error:
ArgumentError in Devise::RegistrationsController#new
wrong number of arguments (given 2, expected 0..1)
I use multiply singup in my app and other work good
My callback controller:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable, omniauth_providers: %i[google_oauth2 twitter github]
def self.from_omniauth(auth, _signed_in_resource = nil)
user = User.where(provider: auth.provider, uid: auth.uid).first
if user.present?
user
else
user_with_email = User.find_by_email(auth.info.email)
if user_with_email.present?
user = user_with_email
else
user = User.new
if auth.provider == 'github'
user.provider = auth['provider']
user.uid = auth['uid']
user.oauth_user_name = auth['info']['name']
user.email = auth['info']['email']
user.save
elsif auth.provider == 'twitter'
user.provider = auth.provider
user.uid = auth.uid
user.oauth_token = auth.credentials.token
user.oauth_expires_at = auth.extra.raw_info.name
elsif auth.provider == 'google_oauth2'
user.provider = auth.provider
user.uid = auth.uid
user.oauth_token = auth.credentials.token
user.first_name = auth.info.first_name
user.last_name = auth.info.last_name
user.email = auth.info.email
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save
end
end
end
user
end
def self.new_with_session(params, session)
if session['devise.user_attributes']
new(session['devise.user_attributes'], without_protection: true) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
def password_required?
super && provider.blank?
end
end
Thank you for attention and help.
Related
I got some problem with OmniAuth FaceBook login into my webapp.
Tell me please, what should i edit to fix this error? Check the code.
Error in the browser:
undefined method `to_a' for "Name Surname":String
User.rb:
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
x = auth.info.name.to_a
user.name = x[0]
user.surname = x[1]
user.login = auth.info.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
Omniauth_callback_controller.rb :
def facebook
if request.env["omniauth.auth"].info.email.blank?
redirect_to "/users/auth/facebook?auth_type=rerequest&scope=email"
end
#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"]
if(#user.surname.nil?)
redirect_to new_profile_path
else
redirect_to my_profile_path
end
end
end
devise.rb :
config.omniauth :facebook, '*********', '*********', {:client_options => {:ssl => {:verify => false}}}
name is a string and you are trying to convert it to array
x = auth.info.name.to_a
use split instead
x = auth.info.name.split
#=> ['Name', 'Surname']
You can make use of OmniAuth first_name and last_name:
Update your devise.rb:
config.omniauth :facebook, '*********', '*********', info_fields: 'email, first_name, last_name', {:client_options => {:ssl => {:verify => false}}}
and your user.rb:
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.name = auth.info.first_name
user.surname = auth.info.last_name
user.login = auth.info.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
your user.rb should be like this
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
x = auth.info.name.split
if x.count > 1
user.name = x[0]
user.surname = x[1]
else
user.name = x[0]
end
user.login = auth.info.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
But I would suggest to store in a single field, because name can be of more than two words so it would become difficult to identify name and surname.
this link should also help
I'm getting the error: "couldn't find user with id" when trying to sign in with facebook. I want it where if a user is had already been created it triggers the first set of code in the conditional and if the user is new it triggers the second set of code:
sessions_controller
def facebook
preexisting_user = User.find(params[:id]) # What should go in this line?
user = User.from_omniauth(env["omniauth.auth"])
if preexisting_user
cookies.permanent.signed[:user_id] = user.id
redirect_to root_url
flash.now[:info] = 'Welcome Back to Live to Challenge!'
else
action = session.delete(:challenge_action)
user.challenges.create(action: action)
user.send_welcome_email
user.remember
cookies.permanent.signed[:user_id] = user.id
redirect_to tutorial_url
flash.now[:info] = 'Welcome to Live to Challenge!'
end
end
user.rb
def self.from_omniauth(auth)
# Sets 60 day auth token
oauth = Koala::Facebook::OAuth.new("154037ewr2976229929", "ee917abf2ere8f1c98274cdfwqreaebb1346f4")
new_access_info = oauth.exchange_access_token_info auth.credentials.token
new_access_token = new_access_info["access_token"]
new_access_expires_at = DateTime.now + new_access_info["expires"].to_i.seconds
where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
user.provider = auth.provider
user.image = auth.info.image
user.uid = auth.uid
user.name = auth.info.name
user.oauth_token = new_access_token # auth.credentials.token <- your old token. Not needed anymore.
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.password = (0...8).map { (65 + rand(26)).chr }.join
user.email = SecureRandom.hex + "#mailinator.com" unless user.email.present?
user.activated = true
user.save!
end
end
You can try below code, i am sure it will work.
def facebook
user = User.from_omniauth(env["omniauth.auth"])
# preexisting_user = User.find(params[:id]) # What should go in this line?
# user.persisted? is what you need to add if you want to add here
# if user pre existed, it will execute if block otherwise else block.
# checks if pre-existing user
if user.persisted?
cookies.permanent.signed[:user_id] = user.id
redirect_to root_url
flash.now[:info] = 'Welcome Back to Live to Challenge!'
else
action = session.delete(:challenge_action)
user.challenges.create(action: action)
user.send_welcome_email
user.remember
cookies.permanent.signed[:user_id] = user.id
redirect_to tutorial_url
flash.now[:info] = 'Welcome to Live to Challenge!'
end
end
On My current app that i'm developing, i can sign up using Facebook and Google+. But when I added the ability for signing up with just a regular email, i got this error, I'll appreciate some help please ...
Here are some of my code
#SessionsController
def create
#user = User.from_omniauth(env["omniauth.auth"])
# session[:user_id] = #user.id
# redirect_to root_path
#user = User.find_by_email params[:email]
if #user && #user.authenticate(params[:password])
session[:user_id] = #user.id
redirect_to root_path
else
flash[:alert] = "Wrong email or password"
render :new
end
end
#user.rb
class User < ActiveRecord::Base
has_secure_password
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.image = auth.info.image
user.gender = auth.extra.raw_info.gender
user.location = auth.extra.raw_info.location.name
user.location = auth.extra.raw_info.locale
# user.url = auth_hash['info']['urls'][user.provider.capitalize]
user.save
end
end
So When attempting to signUp with using the email, here's what happen !
enter image description here
I'm guessing that error coming because i'm calling from_omniauth and i'm not passing a provider, which i don't need to use in this case.
You might consider starting fresh - using https://github.com/plataformatec/devise and then adding OmniAuth on top of this (https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview).
How to use ActiveRecord::Base.transaction after first_or_create ?
here is my model method:
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.password = 'password'
user.password_confirmation = 'password'
user.crypted_password = 'password'
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
In my controller:
def social_login
#user = User.from_omniauth(env["omniauth.auth"])
ActiveRecord::Base.transaction do
add_sites(#user)
#user.mobile = mobile_view?
#user.addresses.last.email = #user.email
add_point_to_customer(#user)
#user.add_mail_subscription_if_doesnt_exist(active_site)
end
end
Here is my controller
def social_login
user = User.from_omniauth(env["omniauth.auth"])
session_params = user.attributes.merge("email" => user.email, "password" => user.crypted_password)
#user_session ||= UserSession.new(session_params, true)
if #user_session.save
user = User.where(email: #user_session.email).first
redirect_to root_path, :notice => "Signed in succesfully from #{env["omniauth.auth"].provider.titleize}. Greetings #{user.name.titleize} ;)"
else
flash.now[:alert] = "Sign in failed."
render "new"
end
end
here is the model to handle the omniauth process
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.password = auth.credentials.token
user.password_confirmation = auth.credentials.token
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
I always getting error when trying to save the session. It says:
Authlogic::Session::Existence::SessionInvalidError: Your session is invalid and has the following errors: Email is not valid
can you guys help me? thanks
Did you enable the email permission in your facebook app config/rails's initializion?
Like this:
config.omniauth :facebook, "APP_ID", "APP_SECRET", {:scope => 'email,...'}