Retrieving photo from Facebook using passport-facebook

14,090

Solution 1

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.

Solution 2

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.

Solution 3

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.

Solution 4

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}`
  //
}))
Share:
14,090

Related videos on Youtube

user2897777
Author by

user2897777

Updated on September 14, 2022

Comments

  • user2897777
    user2897777 over 1 year

    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));
    
    • user2897777
      user2897777 almost 10 years
      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.
  • leofontes
    leofontes over 7 years
    ooooooh okay, got it! Thank you :D
  • im.pankratov
    im.pankratov over 6 years
    BTW, you can't use 'picture.type(large)' and 'photos' together