Here is my method:
removeRole: function(role) {
check(role, String);
var user = Meteor.user();
if (!user || ! AccountsAdmin.checkForAdminAuthentication(user))
throw new Meteor.Error(401, "You need to be an authenticated admin");
// handle non-existing role
if (Meteor.roles.find({name: role}).count() < 1 )
throw new Meteor.Error(422, 'Role ' + role + ' does not exist.');
if (role === 'admin')
throw new Meteor.Error(422, 'Cannot delete role admin');
// remove the role from all users who currently have the role
// if successfull remove the role
Meteor.users.update(
{roles: role },
{$pull: {roles: role }},
{multi: true},
function(error) {
if (error) {
throw new Meteor.Error(422, error);
} else {
Roles.deleteRole(role);
}
}
);
},
Here is the error I receive when looking at the call in Kadira:
message: After filtering out keys not in the schema, your modifier is now empty
stack:
Error: After filtering out keys not in the schema, your modifier is now empty
at [object Object].doValidate (packages/aldeed_collection2-core/lib/collection2.js:282:1)
at [object Object]._.each.Mongo.Collection.(anonymous function) [as update] (packages/aldeed_collection2-core/lib/collection2.js:83:1)
at [object Object].Meteor.methods.removeRole (packages/accounts-admin-ui-bootstrap-3/server/methods.js:86:1)
Line 86 of that methods.js is “Meteor.users.update” in the code above. When trying to debug this using breakpoints it appears this is where the error is happening as well.
I am using this package to help with the user management UI that I am creating, although I have did some customizing to it. I have also tested this on a different version of my project for troubleshooting and I have found that it works when I don’t use the Collection2 package/my custom schema. I’m not too sure what the exact issue is, but I’m guessing I need to add something to the schema but I’m not sure what…
Here is my custom schema setup:
Schema = {};
Schema.UserProfile = new SimpleSchema({
userProfile: {
type: Object
},
'userProfile.firstName': {
type: String,
optional: true,
label: "First Name"
},
'userProfile.lastName': {
type: String,
optional: true,
label: "Last Name"
},
'userProfile.birthday': {
type: Date,
optional: true,
label: "Date of Birth"
},
'userProfile.contactEmail': {
type: String,
optional: true,
label: "Email"
},
'userProfile.gender': {
type: String,
allowedValues: ['Male', 'Female'],
optional: true,
label: "Gender"
},
'userProfile.address': {
type: String,
optional: true,
label: "Address"
},
'userProfile.city': {
type: String,
optional: true,
label: "City"
},
'userProfile.stateProvince': {
type: String,
optional: true,
label: "State/Province"
},
'userProfile.postalCode': {
type: String,
optional: true,
label: "Postal Code"
},
'userProfile.phoneNumber': {
type: String,
optional: true,
label: "Phone Number"
},
userProfilePayment: {
type: Object
},
'userProfilePayment.paymentEmail': {
type: String,
optional: true,
label: "Payment Email"
},
'userProfilePayment.address': {
type: String,
optional: true,
label: "Address"
},
'userProfilePayment.city': {
type: String,
optional: true,
label: "City"
},
'userProfilePayment.stateProvince': {
type: String,
optional: true,
label: "State/Province"
},
'userProfilePayment.postalCode': {
type: String,
optional: true,
label: "Postal Code"
},
'userProfilePayment.phoneNumber': {
type: String,
optional: true,
label: "Phone Number"
},
});
Schema.User = 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.
// Third-party login packages may not require either. Adjust this schema as necessary for your usage.
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.
// Third-party login packages may not require either. Adjust this schema as necessary for your usage.
optional: true
},
"emails.$": {
type: Object
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email
},
"emails.$.verified": {
type: Boolean
},
createdAt: {
type: Date
},
profile: {
type: Schema.UserProfile,
optional: true
},
// Make sure this services field is in your schema if you're using any of the accounts packages
services: {
type: Object,
optional: true,
blackbox: true
},
// Add `roles` to your schema if you use the meteor-roles package.
// Option 1: Object type
// If you specify that type as Object, you must also specify the
// `Roles.GLOBAL_GROUP` group whenever you add a user to a role.
// Example:
// Roles.addUsersToRoles(userId, ["admin"], Roles.GLOBAL_GROUP);
// You can't mix and match adding with and without a group since
// you will fail validation in some cases.
roles: {
type: Object,
optional: true,
blackbox: true
},
// In order to avoid an 'Exception in setInterval callback' from Meteor
heartbeat: {
type: Date,
optional: true
},
// Added to work with mizzao:user-status
status: {
type: Object,
optional: true,
blackbox: true
}
});
Meteor.users.attachSchema(Schema.User);
Meteor.users.allow({
// NOTE: The client should not be allowed to add users directly!
insert: function(userId, doc) {
// only allow posting if you are logged in
console.log("doc: " + doc + " userId: " + userId);
return !! userId;
},
update: function(userId, doc, fieldNames) {
// only allow updating if you are logged in
console.log("doc: " + doc + " userId: " + userId);
// NOTE: a user can only update his own user doc and only the 'userProfile' and 'userProfilePayment' field
return !! userId && userId === doc._id && _.isEmpty(_.difference(fieldNames, ['userProfile, userProfilePayment']));
},
/* NOTE: The client should not generally be able to remove users
remove: function(userID, doc) {
//only allow deleting if you are owner
return doc.submittedById === Meteor.userId();
}
*/
});
I’m fairly new to Meteor so any help would be greatly appreciated!