12

I'm trying to get the authenticated Facebook user's profile picture, to use within a Meteor application. I've tried the following

Meteor.publish("facebook_avatar_url", function() {
    return Meteor.users.find({_id: this.userId}, {fields: {
        'services.facebook.id': 1,
        'services.facebook.name': 1,
        'services.facebook.gender': 1,
        'services.facebook.picture': 1,
        'services.facebook.picture.data': 1,
        'services.facebook.picture.data.url': 1
    }});
});

and it only returns the id, name, and gender. This seems to be what I want, and the recommended solution. Only problem is there's no data being returned regarding the user's picture.

I tried adding the following to server/server.js, at the suggestion of some other posts, but it a) doesn't seem to be the recommended approach, and b) doesn't seem to be doing anything. So, it seems to be a dead end, but somebody out there seems to think that it can be used to get the profile picture loaded up.

var getFbPicture;

Accounts.loginServiceConfiguration.remove({
    service: "facebook"
});


Accounts.onCreateUser(function(options, user) {
    if (options.profile) {
        options.profile.picture = getFbPicture(user.services.facebook.accessToken);
        user.profile = options.profile;
    }
    return user;
});

getFbPicture = function(accessToken) {
    var result;
    result = Meteor.http.get("https://graph.facebook.com/me", {
        params: {
            access_token: accessToken,
            fields: 'picture'
        }
    });
    if (result.error) {
        throw result.error;
    }
    return result.data.picture.data.url;
};

So, I'm kinda unsure which direction to go at this point. Is this something that needs permissions set on the Facebook Graph API? Or on the Facebook Application? Do I have the syntax wrong in the publication function? Do I need to revisit the onCreateUser function?

Sphinxxx
  • 12,484
  • 4
  • 54
  • 84
AbigailW
  • 893
  • 12
  • 20

2 Answers2

36

Use this instead, you don't need an access token or anything special to get their profile picture, just their facebook user id.

Accounts.onCreateUser(function(options, user) {
    if (options.profile) {
        options.profile.picture = "http://graph.facebook.com/" + user.services.facebook.id + "/picture/?type=large";
        user.profile = options.profile;
    }
    return user;
});
Tarang
  • 75,157
  • 39
  • 215
  • 276
  • 3
    Thanks for the feedback Akshat. The Accounts.onCreateUser method actually broke my application's bootstrapping of users, but the general idea worked, so accepting the answer. I wound up using the following: `Template.userCardTemplate.user_image = function () { if(Meteor.user().services.facebook){ return "http://graph.facebook.com/" + Meteor.user().services.facebook.id + "/picture/?type=large"; } };` – AbigailW Feb 22 '13 at 17:53
  • Please I want you to be able to use it as you wanted! It shouldn't break your app, are you using it on server side code? do you get errors on your console with it & are you passing the options down when registering? – Tarang Feb 22 '13 at 18:00
  • What you suggested is good code, and uses the framework correctly. I just happen to have been bypassing the Accounts module when bootstrapping users, and inserting them directly into the Users collection. The error is on my side, because I'm using a secondary, non-standard mechanism to bootstrap users. I have to rethink that that bootstrap file, and figure out how to refactor it using the Accounts module. (Maybe even submit a bug fix for the 'todos' example, to bring it up to speed with the latest developments with the Accounts module.) – AbigailW Feb 22 '13 at 18:16
  • I'm trying this but is not working. nothing happens. It's not being added to the database. should this still works with the new meteor version? – Rafael Jan 18 '15 at 02:48
  • Hi Rafael, it should work. Are you sure you ran "meteor add accounts-facebook", and entered your app's id and secret? If yes then please open a terminal windon, run "meteor mongo", and type "db.users.findOne()". What is the result? – Stenio Ferreira Feb 04 '15 at 06:54
3

if you want to get picture for facebook

Accounts.onCreateUser(function(options, user) {
    if (typeof(user.services.facebook) != "undefined") {
        user.services.facebook.picture = "http://graph.facebook.com/" + user.services.facebook.id + "/picture/?type=large";
    }
    return user;
});

you can to add this helper function

UI.registerHelper("getImageUser", function (userId) {
    var user= Meteor.users.findOne(userId);
    if (user.services)
    {
        if (user.services.facebook)
            return user.services.facebook.picture;
        if (user.services.twitter)
            return user.services.twitter.profile_image_url;
        if (user.services.google)
            return user.services.google.picture;
    }
    else
    {
        return "images/withOutPhoto.png";
    }
});

in your html

<img src="{{getImageUser this._id}}" alt="...">
Walter Zalazar
  • 541
  • 4
  • 11
  • 1
    do not forget : user.profile = options.profile; this one will overwrite the default one, and you will loose the name where the sign in/up is. Well it did for me ^^ – roro_57 Nov 02 '14 at 21:09