Issue when login and register with Facebook in Meteor


#1

I’m trying to use Facebook to connect and register into my Meteor.js application. In my login template I put a button to do this. I call the function Meteor.loginWithFacebook() but it doesn’t work… I’m guessing that Meteor try to create a new user and that it doesn’t find the username information but I don’t know how to manage that.

My handler to call the login :

'click #facebook-login': function(event) {
    Meteor.loginWithFacebook({}, function(err){
        if (err) {
            throw new Meteor.Error("Facebook login failed");
            Materialize.toast('Echec de connexion!', 4000);
        }
        else {
            Router.go(Utils.pathFor('home'));
            Materialize.toast('Bon retour parmis nous ' + Meteor.user().username + ' !', 5000);
        }
    });
}

The error I have :

I20160428-12:44:56.099(2)? Exception while invoking method 'login' Error: Nom d'utilisateur is required
I20160428-12:44:56.100(2)?     at getErrorObject (packages/aldeed_collection2-core/lib/collection2.js:437:1)
I20160428-12:44:56.101(2)?     at [object Object].doValidate (packages/aldeed_collection2-core/lib/collection2.js:420:1)
I20160428-12:44:56.101(2)?     at [object Object].Mongo.Collection.    (anonymous function) [as insert] (packages/aldeed_collection2-core/lib/collection2.js:173:1)
I20160428-12:44:56.101(2)?     at AccountsServer.Ap.insertUserDoc (packages/accounts-base/accounts_server.js:1250:25)
I20160428-12:44:56.101(2)?     at AccountsServer.Ap.updateOrCreateUserFromExternalService (packages/accounts-base/accounts_server.js:1386:20)
I20160428-12:44:56.102(2)?     at [object Object].Package (packages/accounts-oauth/oauth_server.js:55:1)
I20160428-12:44:56.103(2)?     at packages/accounts-base/accounts_server.js:464:32
I20160428-12:44:56.103(2)?     at tryLoginMethod (packages/accounts-base/accounts_server.js:241:14)
I20160428-12:44:56.103(2)?     at AccountsServer.Ap._runLoginHandlers (packages/accounts-base/accounts_server.js:461:18)
I20160428-12:44:56.103(2)?     at [object Object].methods.login (packages/accounts-base/accounts_server.js:524:27)
I20160428-12:44:56.129(2)? Sanitized and reported to the client as: Nom d'utilisateur is required [400]

Thank’s for any help !


#2

Did you include the serviceConfiguration code? for example in server/main.js:

import { Meteor } from 'meteor/meteor';
import { ServiceConfiguration } from 'meteor/service-configuration';

Meteor.startup(() => {
  ServiceConfiguration.configurations.upsert(
    { service: 'facebook' },
    {
      $set: {
        clientId: 'xxxxxx',
        loginStyle: 'popup',
        secret: 'yyyyyyy',
      },
    }
  );
});

Incidentally, your helper can be simplified a little in ES2015:

'click #facebook-login'() {
    Meteor.loginWithFacebook(err => {
        if (err) {
            throw new Meteor.Error("Facebook login failed");
            Materialize.toast('Echec de connexion!', 4000);
        }
        else {
            Router.go(Utils.pathFor('home'));
            Materialize.toast('Bon retour parmis nous ' + Meteor.user().username + ' !', 5000);
        }
    });
}

#3

Thank’s for your answer, I change my helper to match ES2015 !

I change my code and I add a hook for account creation, now I don’t have any error on the server side but one in the client side which don’t explain anything… :frowning:

This is my hook :

Accounts.onCreateUser(function(options, user) {
    var emails = [{"address":user.email || user.services.facebook.email || user.services.twitter.email || user.services.google.email,"verified":true}]
  user.username = user.username || Utils.formatUsername(user.services.facebook.name) || Utils.formatUsername(user.services.twitter.name) || Utils.formatUsername(user.services.google.name);
  user.emails = emails;
  return user;
});

Now the schema of my database :

Globals.schemas.UserProfile = new SimpleSchema({
    firstName: {
        type: String,
        regEx: /^[a-zA-Z-]{2,25}/,
        optional: true,
        label: "Prénom"
    },
    lastName: {
        type: String,
        regEx: /^[a-zA-Z-]{2,25}/,
        optional: true,
        label: "Nom"
    },
    birthDay: {
        type: Date,
        optional: true,
        label: "Date de naissance",
        min: new Date("1900-01-01T00:00:00.000Z"),
        autoform: {
            value: new Date("1900-10-18T00:00:00.000Z")
        }
    },
    gender: {
        type: String,
        allowedValues: ['M', 'F'],
        optional: true,
        label: "Genre",
        autoform: {
            options: [
                {
                    label: "Homme",
                    value: "M"
                },
                {
                    label: "Femme",
                    value: "F"
                }
            ],
            firstOption: "(Veuillez sélectionner une réponse)"
        }
    },
    level: {
        type: Number,
        autoValue: function () {
            if (this.isInsert) {
                return 1;
            }
        },
        autoform: {
            omit: true
        },
        min: 0,
        max: 1000,
        label: "Niveau"
    },
    picture: {
        type: String,
        optional: true,
        autoform: {
            omit: true
        },
        label: "Photo"
    }
});

// Schéma principal
Globals.schemas.User = new SimpleSchema({
    username: {
        type: String,
        regEx: /^[a-z0-9A-Z_]{3,30}$/,
        label: "Nom d'utilisateur"
    },
    password: {
        type: String,
        label: "Mot de passe",
        optional: true,
        autoform: {
            afFieldInput: {
                type: "password"
            }
        }
    },
    confirmation: {
        type: String,
        label: "Confirmation",
        optional: true,
        custom: function(){
            if(this.value !== this.field('password').value){
                return "passwordMissmatch";
            }
        },
        autoform: {
            afFieldInput: {
                type: "password"
            }
        }
    },
    emails: {
        type: [Object],
        optional: false,
        label: "Adresses Email"
    },
    "emails.$.address": {
        type: String,
        regEx: SimpleSchema.RegEx.Email,
        label: "Adresses Email"
    },
    "emails.$.verified": {
        type: Boolean,
        optional: true,
        autoform: {
            omit: true
        }
    },
    createdAt: {
        type: Date,
        autoValue: function () {
            if (this.isInsert) {
                return new Date;
            } else {
                this.unset();
            }
        },
        autoform: {
            omit: true
        }
    },
    profile: {
        type: Globals.schemas.UserProfile,
        optional: true
    },
    services: {
        type: Object,
        optional: true,
        blackbox: true,
        autoform:{
            omit: true
        }
    },
    roles: {
        type: Object,
        optional: true,
        blackbox: true,
        autoform: {
            omit: true
        }
    }
}); 

I have this error on my console :

Exception in delivering result of invoking 'login': Error: [Facebook login failed]
    at http://localhost:3000/app/app.js?hash=87427f629e0413869c89522c0500e7151fc7aafd:971:27
    at Accounts.callLoginMethod.userCallback (http://localhost:3000/packages/accounts-oauth.js?hash=ac90001ebf17b2b7e1ebf1370330775b19248242:165:7)
    at http://localhost:3000/packages/accounts-base.js?hash=9a2df45ebeba9d14f693547bc91555a09feda78e:322:26
    at http://localhost:3000/packages/underscore.js?hash=27b3d669b418de8577518760446467e6ff429b1e:794:19
    at loggedInAndDataReadyCallback (http://localhost:3000/packages/accounts-base.js?hash=9a2df45ebeba9d14f693547bc91555a09feda78e:422:7)
    at ._callback (http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:1105:22)
    at _.extend._maybeInvokeCallback (http://localhost:3000/packages/ddp-client.js?hash=b5f1b97df6634673c68f37914ae9f4c3231c438e:3541:12)
    at _.extend.receiveResult (http://localhost:3000/packages/ddp-client.js?hash=b5f1b97df6634673c68f37914ae9f4c3231c438e:3561:10)
    at _.extend._livedata_result (http://localhost:3000/packages/ddp-client.js?hash=b5f1b97df6634673c68f37914ae9f4c3231c438e:4675:9)
    at onMessage (http://localhost:3000/packages/ddp-client.js?hash=b5f1b97df6634673c68f37914ae9f4c3231c438e:3369:12) 

And yes I include the serviceConfiguration like this :

ServiceConfiguration.configurations.remove({
    service: 'facebook'
});

ServiceConfiguration.configurations.insert({
    service: 'facebook',
    appId: 'appId',
    secret: 'secret'
});

I don’t understand what doesn’t work… I will test with the others services Twitter and Google !

Thank’s for helping