Retrieving photo from Facebook using passport-facebook
Asked Answered
S

5

17

I am able to retrieve basic user information via passport-facebook, following the below code and saving in mongodb:

app.get("/auth/facebook", passport.authenticate("facebook", { scope : ["email", "publish_stream", "user_location", "user_hometown", "user_birthday", "read_friendlists"]}));

app.get("/auth/facebook/callback", passport.authenticate("facebook",{ successRedirect: '/', failureRedirect: '/'}));

var mongoose = require('mongoose'), 
FacebookStrategy = require('passport-facebook').Strategy, 
Users = mongoose.model('Users');

module.exports = function (passport, config) { 
passport.serializeUser(function(user, done) { 
    done(null, user.id);
}); 

passport.deserializeUser(function(id, done) { 
    Users.findOne({ _id: id }, function (err, user) { 
        done(err, user); 
    });
});

passport.use(new FacebookStrategy({ 
    clientID: config.facebook.clientID,
    clientSecret: config.facebook.clientSecret,
    callbackURL: config.facebook.callbackURL 
}, function(accessToken, refreshToken, profile, done) { 
    Users.findOrCreateFaceBookUser(profile, done);
}));};

However, I am not able to see the profile picture in the "profile".

The documentation https://github.com/jaredhanson/passport-facebook says to retrieve photos we need to pass the profileFields as below. But doing so, I am able to see the photo URL but loosing other data which were contained in _json e.g. profile._json.location.name. How can I retrieve photo with other user information intact?

passport.use(new FacebookStrategy({
// clientID, clientSecret and callbackURL
profileFields: ['id', 'displayName', 'photos', ....]},// verify callback));
Shiksa answered 18/11, 2013 at 4:13 Comment(2)
Did you ever figure this one out?Month
Yes, the picture can be accessed via the graph api using the access token like this. "graph.facebook.com" + profile.username + "/picture" + "?width=200&height=200" + "&access_token=" + accessToken; There is no need to use the profile fields.Shiksa
S
9

Yes, the picture can be accessed via the graph api using the access token like this. "graph.facebook.com/"; + profile.username + "/picture" + "?width=200&height=200" + "&access_token=" + accessToken; There is no need to use the profile fields.

Shiksa answered 21/4, 2014 at 18:18 Comment(0)
B
27

If you need a larger image (default in miksii's example above is 50px x 50px which is pretty small), then use:

profileFields: ['id', 'displayName', 'name', 'gender', 'picture.type(large)']

and then

picture: profile.photos ? profile.photos[0].value : '/img/faces/unknown-user-pic.jpg'

This will return a 200px x 200px profile picture for that user.

Batik answered 12/3, 2016 at 12:4 Comment(1)
BTW, you can't use 'picture.type(large)' and 'photos' togetherTifanie
P
16

In addition to answer of your question - you don't have to do it that way. As you mentioned you can define the required attributes for Facebook profile:

  clientID: "...",
  clientSecret: "...",
  callbackURL: "...",
  profileFields: ['id', 'displayName', 'name', 'gender', ..., 'photos']

What than you can do is just simply grab the value of the given attribute. Let's say you want to make an attribute that will hold this value:

picture: profile.photos ? profile.photos[0].value : '/img/faces/unknown-user-pic.jpg'

This proved to be a better solution since some users or sometimes the value of username may be undefined.

I hope you find this useful too,

Thank you.

Phosphocreatine answered 24/1, 2015 at 23:53 Comment(2)
I know this is over a year old, but can you explain why you use the structure with ? and : instead of just setting a value? Trying to understand what is going on, thank you :)Corcyra
It is shorten if - else conditional structure where ? means "in case profile.photos returns true" and : means "in case profile.photos returns false". Regarding to that, if there is no photos we want to set the default picture for our user (this picture rest in the specified path img/faces/unknown..jpg).Phosphocreatine
S
9

Yes, the picture can be accessed via the graph api using the access token like this. "graph.facebook.com/"; + profile.username + "/picture" + "?width=200&height=200" + "&access_token=" + accessToken; There is no need to use the profile fields.

Shiksa answered 21/4, 2014 at 18:18 Comment(0)
T
1

As this answer, it will be work better with this code.

passport.use(new FacebookStrategy({
  clientID: FACEBOOK_APP_ID,
  clientSecret: FACEBOOK_APP_SECRET,
  callbackURL: FACEBOOK_APP_CALLBACK,
  profileFields: ['id', 'displayName', 'picture.type(large)', 'email', 'birthday', 'friends', 'first_name', 'last_name', 'middle_name', 'gender', 'link']
}, (accessToken, refreshToken, profile, cb) => {
  const picture = `https://graph.facebook.com/${profile.id}/picture?width=200&height=200&access_token=${accessToken}`
  //
}))
Tollbooth answered 22/11, 2019 at 4:14 Comment(0)
H
0

2020 solution

Get users accessToken from passportjs passport-facebook strategy.
Use this token to get json with a url for an users avatar:

https://graph.facebook.com/me/picture?access_token=${accessToken}&&redirect=false
History answered 20/7, 2020 at 0:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.