junkystu
junkystu

Reputation: 1487

Laravel Socialite first and last name

I'm adding social authentication to an application using Laravel's Socialite. I can retrieve the full name but not the first and last names separately. After the callback happens and Socialite is handling it, the user is retrieved successfully. If I am to dump the user I get back from $user = this->social->driver('facebook')->user(); I get the following:

object(Laravel\Socialite\Two\User)#459 (8) {
     ["token" ]=> string(209) "{token}"
     ["id"] => string(17) "{socialID}"
     ["nickname"] => NULL
     ["name"] => string(14) "{Full Name}"
     ["email"] => string(19) "{Email address}"
     ["avatar"] => string(69) "https://graph.facebook.com/v2.4/{socialID}/picture?type=normal"
     ["user"] => array(6) {
        ["first_name"] => string(6) "{First name}"
        ["last_name"] => string(7) "{Last mame}"
        ["email"] => string(19) "{Email address}"
        ["gender"] => string(4) "male"
        ["verified"] => bool(true)
        ["id"] => string(17) "{socialID}"
    }
    ["avatar_original"] => string(68) "https://graph.facebook.com/v2.4/{socialID}/picture?width=1920"

}

I can obtain the full name or email via $user->name or $user->email however, I can not get the separate first and last names. I have tried $user->first_name as well as trying to dump the $user->user array but all I see is undefined property errors.

I do not want to do something weird like extract it from the full name when the separate first and last name are clearly there as it can get ugly when middle names are present.

I have Googled my way around and weirdly, nobody came across this issue. Am I missing something from the docs? Any suggestions on how to retrieve the first and last name from the user array are greatly appreciated.

Upvotes: 8

Views: 15997

Answers (6)

Haritsinh Gohil
Haritsinh Gohil

Reputation: 6272

You can also use offsetGet() method which is defined in AbstractUser class of socialite package, which returns $this->user[$offset]; so using it you can get first name and last name,

but for facebook and google it differs because of their different response so i have given code below for both facebook and google.

For GOOGLE & FACEBOOK

$providerUser = Socialite::driver($provider)->user(); // $provider can be facebook, google etc.

switch($provider){
   case 'facebook':
      $first_name = $providerUser->offsetGet('first_name');
      $last_name = $providerUser->offsetGet('last_name');
      break;

   case 'google':
      $first_name = $providerUser->offsetGet('given_name');
      $last_name = $providerUser->offsetGet('family_name');
      break;

 // You can also add more provider option e.g. linkedin, twitter etc.

   default:
      $first_name = $providerUser->getName();
      $last_name = $providerUser->getName();
}

$user = User::create([
                'first_name' => $first_name,
                'last_name' => $last_name,
                'email' => $providerUser->getEmail(),
                'image' => $providerUser->getAvatar(),
            ]);

Upvotes: 6

nlagdhir
nlagdhir

Reputation: 41

In linkedin you can get first and last name from provider like this.

$linkedinUser = $this->socialite->driver('linkedin')->user());

$attributes = [
        'first_name' => $linkedinUser->user['firstName'],
        'last_name' => $linkedinUser->user['lastName'],
        'email' => $linkedinUser->email,
        'avatar' => $linkedinUser->avatar,
        'linkedin_id' => $linkedinUser->id
    ];

Upvotes: 3

christostsang
christostsang

Reputation: 1841

After coming against the same issue myself, i noticed that all social networks i used for registration/login (Facebook, Twitter, Google+, Github) send back a "name" attribute. This attribute can either be empty (if the user hasn't added any information) or carry a value.

What i did, was to create a method (getFirstLastNames()) that will get that "name" value and break it into first_name and last_name by exploding them when a space or multiple spaces is detected. Then i use them to populate my users table:

protected function getFirstLastNames($fullName)
{
    $parts = array_values(array_filter(explode(" ", $fullName)));

    $size = count($parts);

    if(empty($parts)){
        $result['first_name']   = NULL;
        $result['last_name']    = NULL;
    }

    if(!empty($parts) && $size == 1){
        $result['first_name']   = $parts[0];
        $result['last_name']    = NULL;
    }

    if(!empty($parts) && $size >= 2){
        $result['first_name']   = $parts[0];
        $result['last_name']    = $parts[1];
    }

    return $result;
}

The $fullName variable is:

Socialite::driver($provider)->getName();

For this implementation i assume that:

  1. No matter how many names the user has, i will use the first part of the string as the first_name and the second one as the last_name. [if my name is POPPY PETAL EMMA ELIZABETH DEVERAUX, then i will use POPPY as first_name and PETAL as last_name. The rest will be ignored]. If the "name" attribute comes back empty or with one name, then i insert NULL into the users table where i get no value.
  2. If the user has used multiple spaces while separating the names (or before and after the names), this method will remove them and keep only the strings.

Now that you have the data in the array you can use them while creating the user:

$userFirstLastName = $this->getFirstLastNames(Socialite::driver($provider)->getName());

$user = User::create([
            'email'         => Socialite::driver($provider)->getName()->getEmail(),
            'first_name'    => $userFirstLastName['first_name'],
            'last_name'     => $userFirstLastName['last_name'],
        ]);

ps1: Make sure you change the migrations for users table (Laravel 5.3 uses only "name" field. If you need to have the "first_name" and "last_name" you should change it. Of course run "php artisan migrate:refresh" to implement the changes. All data will be lost.

ps2: Make sure the first_name, last_name and password fields can be nullable. Otherwise you will get an error.

ps3: Inside User model, add first_name and last_name and remove name in the $fillable property.

ps4: [Not Playstation 4] The first_name and last_name values can be altered by the user within your web app, if the above procedure used your second name as first_name or last_name. You can't predict what each user uses as a full name, so you need to make assumptions.

Hope this helps!

Upvotes: 1

Sam
Sam

Reputation: 474

And you could simply do:

$NameArray = explode(' ',$user->getName());
$First_name = $NameArray[0];
$Last_name = $NameArray[1];

Upvotes: 0

Richard Torcato
Richard Torcato

Reputation: 2770

I've found that sometimes the user object won't contain the first and last names unless you specify you need those fields.

//get the driver and set desired fields
$driver = Socialite::driver('facebook')
                ->fields([
                    'name', 
                    'first_name', 
                    'last_name', 
                    'email', 
                    'gender', 
                    'verified'
                ]);
// retrieve the user
$user = $driver->user();

then you can get the first name and last name like this

$user->user['first_name'] and $user->user['last_name']

Other stuff you can ask for:

https://developers.facebook.com/docs/graph-api/reference/user/

for google plus:

$user->firstname = $user->user['name']['givenName'];
$user->lastname = $user->user['name']['familyName'];

Upvotes: 18

omma2289
omma2289

Reputation: 54639

According to the dump of the $user var you should be able to access the name values by doing:

$user->user['first_name'] and $user->user['last_name']

Upvotes: 8

Related Questions