简体   繁体   中英

Meteor - missing username Meteor.users.findOne(); or Meteor.users();

Upon submit of a post, the current user does not seem to be recognised and username appears as blank. The submit html has {{author}} to display the user who wrote the post.

Heres the results when I type the following in the console:

1) user.username

=> result user is undefined.

2) Meteor.users.find();

=> LocalCollection.Cursor {collection: LocalCollection, sorter: null, _selectorId: undefined, matcher: Minimongo.Matcher, skip: undefined…}

3) Meteor.users.findOne();

=> Object {_id: "P3ocCTTdvi2o3JApf", profile: Object}

compared to the working version (Note my version is missing username)

=> Object {_id: "XHXPebzjg5LM5tNAu", profile: Object, username: "Bruno"}

In post.js collection (in the lib folder - shared with both client and server), I have:

Meteor.methods({
  postInsert: function(postAttributes) {
    check(this.userId, String);           //check(Meteor.userId(), String);
    check(postAttributes, {
      title: String,
      message: String
    });
    var user = Meteor.user();
    var post = _.extend(postAttributes, {
      userId: user._id, 
      author: user.username
    });
    var postId = Posts.insert(post);
    return {_id: postId};
  },

There are also no other references to author in the Discover Meteor tutorial, and it worked. However mine doesnt work. This problem seems to have started after I added UserAccounts package. Or perhaps a folder location issue?

Update [11 May 2015]

I realised that when using the original ui-accounts that came with Meteor, it has the username field because the sign up link that came with {{> login}} uses username + password. Theres no email address involved.

UserAccounts on the other hand doesnt have this username field. Its either email/pw or social login. So perhaps someone guide me on how to have username (either as separate field or derived from email) from email/pw and social network button login/signin as a start? Then Ill try to fiddle from there.

code for UserAccounts

router.js

//Iron router plugin to ensure user is signed in
AccountsTemplates.configureRoute('ensureSignedIn', {
  template: 'atTemplate',     //template shown if user is not signed in
  layoutTemplate: 'atLayout'  //template for login, registration, etc
});

Router.plugin('ensureSignedIn', { //Don't require user logged in for these routes
  except: ['login', 'register']   //can use only: too 
});

AccountsTemplates.configureRoute('signIn', {  //login
  name: 'login',
  path: '/login',
  template: 'atTemplate',
  layoutTemplate: 'atLayout',
  redirect: '/'
});

AccountsTemplates.configureRoute('signUp', {  //registration
  name: 'register',
  path: '/register',
  template: 'atTemplate',
  layoutTemplate: 'atLayout',
  redirect: '/'
});

and under config.js (server side)

From the Useraccounts doc, Try this:

if (Meteor.isServer){
    Meteor.methods({
        "userExists": function(username){
            return !!Meteor.users.findOne({username: username});
        },
    });
}

AccountsTemplates.addField({
    _id: 'username',
    type: 'text',
    required: true,
    func: function(value){
        if (Meteor.isClient) {
            console.log("Validating username...");
            var self = this;
            Meteor.call("userExists", value, function(err, userExists){
                if (!userExists)
                    self.setSuccess();
                else
                    self.setError(userExists);
                self.setValidating(false);
            });
            return;
        }
        // Server
        return Meteor.call("userExists", value);
    },
});

This will add the username field to your login/register forms and check for username conflicts when registering new users.

The top part is server code the bottom part is common code, so you could place this whole snippet in project/lib/ folder, or place the method with the rest of your methods, depending on how your structuring your project.

Use the following to have the username field show up first instead of last on the register form:

var pwd = AccountsTemplates.removeField('password');
AccountsTemplates.removeField('email');
AccountsTemplates.addFields([
  {
    _id: "username",
    type: "text",
    displayName: "username",
    required: true,
    func: function(value){
      if (Meteor.isClient) {
        console.log("Validating username...");
        var self = this;
        Meteor.call("userExists", value, function(err, userExists){
          if (!userExists)
            self.setSuccess();
          else
            self.setError(userExists);
          self.setValidating(false);
        });
        return;
      }
      // Server
      return Meteor.call("userExists", value);
    },
    minLength: 5,
  },
  {
    _id: 'email',
    type: 'email',
    required: true,
    displayName: "email",
    re: /.+@(.+){2,}\.(.+){2,}/,
    errStr: 'Invalid email',
  },
  pwd
]);

https://github.com/meteor-useraccounts/core/blob/master/Guide.md

You need to use . s to access properties of objects, not spaces

Meteor.users.findOne

You provided very little information to spot your problem. This said, how are you letting your users in?

Be aware that OAuth registrations do not provide a username field on the created user object, as well as password registration based on email address only. In these cases user.username would be undefined .

I'd suggest to make sure all your users get a profile.username (possibly exploiting some Accounts.onLogin hook or some profile page where to force the user to select a username.

After this you would extend your post metadata setting author: user.profile.username

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM