passport-facebook: Can't get user profile photos.

Hi all, I can’t get the fb user photos as a profile field. Here is my code:

config.js

 passport.use(new FacebookStrategy({
      clientID: config.facebook.clientID,
      clientSecret: config.facebook.clientSecret,
      callbackURL: config.facebook.callbackURL
    },
    function(accessToken, refreshToken, profile, done) {
      console.log(profile)
      User.findOne({ 'facebook.id': profile.id }, function (err, user) {
        if (err) { return done(err) }
        if (!user) {
          user = new User({
            name: profile.displayName,
            email: profile.emails[0].value,
            username: profile.username,
            provider: 'facebook',
            facebook: profile._json,
            photos: profile.picture
          })
          user.save(function (err) {
            if (err) console.log(err)
            return done(err, user)
          })
        }
        else {
          return done(err, user)
        }
      })
    }
  ))

router.js

  app.get('/auth/facebook',
    passport.authenticate('facebook', {
      display: 'popup',
      scope: [ 'email', 'basic_info', 'user_photos'],
      profileFields: ['id', 'displayName', 'photos', 'emails', 'birthday'],
      failureRedirect: '/login'
    }), users.signin)

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Reactions: 1
  • Comments: 15

Most upvoted comments

Hi, No Need to change strategy. Simply add it like this

passport.use(new FacebookStrategy({
      clientID: config.facebook.clientID,
      clientSecret: config.facebook.clientSecret,
      callbackURL: config.facebook.callbackURL, 
      profileFields: ['id', 'name','picture.type(large)', 'emails', 'username', 'displayName', 'about', 'gender'], 
  },

Worked pretty much fine for me. Easy and elegant.

This works - however you cannot user ‘picture.type(large)’ and ‘photos’ together

I have managed to make it work using FB graph api (i think it’s the only way).

// use facebook strategy
  passport.use(new FacebookStrategy({
      clientID: config.facebook.clientID,
      clientSecret: config.facebook.clientSecret,
      callbackURL: config.facebook.callbackURL,
    },
    function(accessToken, refreshToken, profile, done) {
      User.findOne({ 'facebook.id': profile.id }, function (err, user) {
        if (err) { return done(err) }
        if (!user) {
          user = new User({
            name: profile.displayName,
            email: profile.emails[0].value,
            username: profile.username,
            provider: 'facebook',
            facebook: profile._json,
            photos: "https://graph.facebook.com/" + profile.username + "/picture" + "?width=200&height=200" + "&access_token=" + accessToken
          })
          user.save(function (err) {
            if (err) console.log(err)
            return done(err, user)
          })
        }
        else {
          return done(err, user)
        }
      })
    }
  ))

If you don’t want to expose access token, then you need to download the image and serve it from own cdn.

@WIEM-S

scope: ['manage_pages'],

Hi,

I am getting profile pics just fine - profileFields: [‘id’, ‘name’, ‘displayName’, ‘username’, ‘photos’, ‘hometown’, ‘profileUrl’, ‘friends’]

And then in the strategy code…


passport.use(new FacebookStrategy(
      config.facebook, function (authCode, authToken, profile, done) {          
            users.registerFacebookUser({
                facebookid: profile.id,             
                username: profile.username,
                picture: profile.photos ? profile.photos[0].value : '/img/faces/unknown-user-pic.jpg',
                profileUrl: profile.profileUrl,             
            }, authCode, authToken, done);
        }
    ));

The only problem is that if you want to get specific size of a picture - let’s say large. you have to modify strategy.js in _convertProfileFields ()… to… ‘photos’: ‘picture.type(large)’

It would be nice if there was a way to specify picture.type(large) via config vs. modifying it directly… so, for now, you will have standard-size (square-small) picture…

Thanks, Jatin