8

I am now implementing omniauth feature into my app. Everything works fine except that i cant get the first and last name from the facebook. Here is my model code.

    def self.from_omniauth(auth)
    user = User.where(email: auth.info.email).first
    if user
      return user
    else
      where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
        user.provider = auth.provider
        user.uid = auth.uid
        user.first_name = auth.info.first_name
        user.last_name = auth.info.last_name
        user.email = auth.info.email
        user.image = auth.info.image
        user.password = Devise.friendly_token[0,20]
      end
    end

I already have the strong parameters setup properly for devise as am using that now for default authentication and is working properly.Is there any additional permissions necessary for first and last name from facebook?

Abhilash
  • 2,864
  • 3
  • 33
  • 67

3 Answers3

26

After some fiddling around i found the solution. Now i think we have to explicitly require the fields we require. For me the fix is just to add first_name and last_name to facebook.

In my initializers i added first_name and last_name to info fields.

info_fields: 'email, first_name, last_name'

Update

My full config file will look like this now

   config.omniauth :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_SECRET"], scope: 'email', info_fields: 'email, first_name, last_name'
Abhilash
  • 2,864
  • 3
  • 33
  • 67
  • Interesting! What gem are you using? We're using https://rubygems.org/gems/omniauth-facebook/versions/2.0.1 and we don't have to do that. – seddy Oct 13 '15 at 08:56
  • Dont know why...I am using gem "omniauth-facebook" – Abhilash Oct 13 '15 at 10:22
  • Weird, glad you got it solved though :). Where did you find that reference to `info_fields`? – seddy Oct 13 '15 at 10:39
  • 1
    Got it from here https://github.com/mkdynamic/omniauth-facebook/issues/214 ... check the last comment..a life saver.. – Abhilash Oct 13 '15 at 12:54
  • Could you provide a larger code snippet? I added the same to my config file, but I"m still not getting back the data. – RonLugge Mar 30 '16 at 19:29
  • 1
    Thanks Abhilash -- but it turned out to be an update issue. Previous dev had the app pinned to a gem version from the stone age. – RonLugge Mar 30 '16 at 22:52
1

From checking the Facebook docs, the first_name and last_name fields are both part of the public profile so your permissions should be fine.

No idea if this would work (in fact, I would kind of hope it doesn't), but in the implementation we've got working in production at the moment we're using Hash accessors instead of methods. So:

new(
  first_name: oauth_data["info"]["first_name"],                  
  last_name:  oauth_data["info"]["last_name"],     
  ...

Given your email etc fields are getting set correctly, I'd be surprised if trying that works, but it might be worth a shot.

Failing that, have you got any validations or before_create callbacks which could be interfering somehow?

seddy
  • 801
  • 8
  • 16
  • Nope its not working aswell. I tried username instead of firstname and its working fine. I had validations on firstname and lastname but i removed that to make ominiauth work.. Did they change or something or is the firstname and lastname inside info? – Abhilash Oct 13 '15 at 06:13
0

Ran into this issue while designing the OAuth flow for an app that was using Devise + omniauth-facebook.

Using the public_profile scope, you get back a name attribute on the auth hash. request.env["omniauth.auth"]

My issue is that a user has one profile and it is autosaved ( user is required to enter a first name and last name at sign up which is validated on the profile model)

Solution: Create a name parsing method in your omniauth services model, which you can pass the request.env["omniauth.auth"]["info"]["name"] as an argument.

# auth hash returns a name like "John Doe Smith"
def parse_name_from_string(ful_name_string) 
  
   name_array = name_string.split(" ")  # break apart the name

   # I chose to return a PORO so i can do something like parsed_user_name_from_facebook_auth.first_name
   {
     last_name: name_array.pop,
     first_name: name_array.join(" ")
   }
end
Denis S Dujota
  • 543
  • 5
  • 13