Meteor not able to create user after adding attaching schema to users collection

67 views Asked by At

I have installed mizzao:user-status package to track user activity like online, idle status.

I have added status to users collection:

import SimpleSchema from "simpl-schema";

const userSchema = new SimpleSchema({
  status: {
    type: Object,
    optional: true,
  },
  "status.lastlogin": {
    type: Object,
    optional: true,
  },
  "status.lastlogin.date": {
    type: Date,
    optional: true,
  },
  "status.lastlogin.ipAddr": {
    type: String,
    optional: true,
  },
  "status.userAgent": {
    type: String,
    optional: true,
  },
  "status.idle": {
    type: Boolean,
    optional: true,
  },
  "status.lastActivity": {
    type: Date,
    optional: true,
  },
  "status.online": {
    type: Boolean,
    optional: true,
  },
});

Meteor.users.attachSchema(userSchema);

On sign up page I have createUser code:

Accounts.createUser(
      { username, email, password },
      async (error) => {
        if (error && error.reason) {
          setErrors({ signUpFailed: error.reason });
          setIsLoading(false);
          return;
        }
        navigate('/dashboard', { replace: true });
      }
    );

Whenever I try to register I get an error on the server:

Exception while invoking method 'createUser' Error: After filtering out keys not in the schema, your object is now empty

All fields in status are set to optional yet I am still getting this error. If I remove Meteor.users.attachSchema(userSchema); then create user works.

3

There are 3 answers

0
StorytellerCZ On BEST ANSWER

The error is pretty clear. In short it went through your schema, removed things that are not in it and found that it leaves you with empty object. As such you need to define all the other fields that is being used on the users collection. There are two ways how to avoid this issue. First is not to set any schema on the users collection, second is to properly describe everything that is being set and stored there. If you are adjusting the the user documents, then the second approach is best. Bellow is mine description, which also includes definitions for alanning:roles for quick reference. You can find more details on collection2 documentation: https://github.com/Meteor-Community-Packages/meteor-collection2#attach-a-schema-to-meteorusers

const userSchema = new SimpleSchema({
  username: {
    type: String,
    // For accounts-password, either emails or username is required, but not both. It is OK to make this
    // optional here because the accounts-password package does its own validation.
    optional: true
  },
  emails: {
    type: Array,
    // For accounts-password, either emails or username is required, but not both. It is OK to make this
    // optional here because the accounts-password package does its own validation.
    optional: true
  },
  'emails.$': {
    type: Object
  },
  'emails.$.address': {
    type: String,
    regEx: SimpleSchema.RegEx.Email,
    optional: true
  },
  'emails.$.verified': {
    type: Boolean,
    optional: true
  },
  'emails.$.primary': {
    type: Boolean,
    optional: true
  },
  createdAt: {
    type: Date
  },
  profile: {
    type: Object,
    optional: true,
    blackbox: true
  },
  services: {
    type: Object,
    optional: true,
    blackbox: true
  },
  roles: {
    type: Array,
    optional: true
  },
  'roles.$': {
    type: Object,
    optional: true,
    blackbox: true
  },
  // In order to avoid an 'Exception in setInterval callback' from Meteor
  heartbeat: {
    type: Date,
    optional: true
  }
})
0
Igor Loskutov On

You'll probably need to describe

username: {
  type: String
},
emails: {
  type: Array,
  optional: true
},

at least, probably with other fields like profile

0
Christian Fritz On

Sounds like what you are really looking for is https://docs.meteor.com/api/accounts-multi.html#AccountsServer-onCreateUser, which is the callback function you should use to add more fields to the user document when it is created. You don't really need to attach a schema for that, and from your comment the point of the schema was just to extend the user object somehow. If I understood that correctly, then onCreateUser is definitely the way to go.