skip to Main Content

I’ve been stuck with this problem for a day and a half now. What I’m trying to do is create a userProfile section into my Meteor.User collection. So, when the user lands on the ‘settings’ page they could update their information. Here is what I have down.

By the way I’m using the User Accounts package for the signin/signup procedure.

Update: 3
The form submits but no data gets inserted/updated. I have commented out the ‘Schema.User’ because if i put it in and attach it to the Meteor.users.attachSchema(Schema.User). The auto form loads the fields. Which is why I put Schema.UserProfile instead. I checked the console log and it gives me the error “[Access Denied] 403” It must be an allow/deny conflict? I have every code listed on here.

Settings HTML:

<template name="settings">
<div class="text-center light-container" id="settings-section">
    {{> quickForm collection="Meteor.users" doc=currentUser id="userProfile" type="update"}}
</div>

Settings JS In Both Directory

    Schema = {};

Schema.UserProfile = new SimpleSchema({
    userProfile: {
        type: Object
    },
    'userProfile.firstName':{
        type: String,
        label: "First Name",
        max: 80
    },
    'userProfile.lastName':{
        type: String,
        label: "Last Name",
        max: 80
    },
    'userProfile.gender':{
        type: String,
        label: "Gender",
        allowedValues: ["Male", "Female"]
    },
    'userProfile.birthday':{
        type: Date,
        label: "Date Of Birth",
        autoform: {
            type: "bootstrap-datepicker"
        }
    },
    address:{
        type: Object
    },
    'address.city':{
        type: String,
        label: "City/Province",
        max: 80
    },
    'address.state':{
        type: String,
        label: "State",
        max: 80
    },
    'address.country':{
        type: String,
        label: "Country",
        max: 80
    },
    /*privacy:{
        type: String,
        label: "Privacy",
        allowedValues: ["On", "Off"]
    }, */
    aboutYou:{
        type: String,
        label: "About You",
        autoform: {
            afFieldInput: {
                type: "textarea"
            }
        },
        max: 400
    },
    socialNetworks:{
        type: Object,
        label: "Social Networks"
    },
    'socialNetworks.facebook':{
        type: String,
        label: "Facebook",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.instagram':{
        type: String,
        label: "Instagram",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.tumblr':{
        type: String,
        label: "Tumblr",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.twitter':{
        type: String,
        label: "Twitter",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    }
});


/* 
    Schema.User = new SimpleSchema({
        username: {
            type: String,
            regEx: /^[a-z0-9A-Z_]{3,15}$/,
            optional: true
        },
        emails: {
            type: [Object],
            // this must be optional if you also use other login services like facebook,
            // but if you use only accounts-password, then it can be required
            optional: true
        },
        "emails.$.address": {
            type: String,
            regEx: SimpleSchema.RegEx.Email
        },
        "emails.$.verified": {
            type: Boolean
        },
        createdAt: {
            type: Date
        },
        profile: {
            type: Schema.UserProfile,
            optional: true
        },
        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
        }

        */
    }); 

*/

Meteor.users.attachSchema(Schema.UserProfile);

Meteor.users.allow({
    insert: function(userId, doc) {
        // only allow posting if you are logged in
        console.log("doc: " + doc + " userId: " + userId);
        return !! userId;
    },
    update: function(userId, doc) {
        // only allow updating if you are logged in
        console.log("doc: " + doc + " userId: " + userId);
        return !! userId;
    },
    remove: function(userID, doc) {
        //only allow deleting if you are owner
        return doc.submittedById === Meteor.userId();
    }
});

Settings JS in Client Directory

/*
    var postHooks = {
        before: {
            insert: function(doc) {
                if(Meteor.userId()){
                    doc.userId = Meteor.userId();
                }

                return doc;
            }
        },
        docToForm: function(doc) {
            if (_.isArray(doc.tags)) {
                doc.tags = doc.tags.join(", ");
            }
            return doc;
        },
        formToDoc: function(doc) {
            if (typeof doc.tags === "string") {
                doc.tags = doc.tags.split(",");
            }
            return doc;
        }
    };

    AutoForm.addHooks('UserProfile', postHooks);

*/

If anyone can point me into the right direction that would be really helpful!!

2

Answers


  1. You need to create a schema for your profile and then assign it to the user object’s schema in the profile field. I’ve done it for you below.

    var Schema = {};
    
    Schema.UserProfile = new SimpleSchema({
       firstName:{
            type: String,
            label: "First Name",
            max: 80
        },
        lastName:{
            type: String,
            label: "Last Name",
            max: 80
        },
        gender:{
            type: String,
            label: "Gender",
            allowedValues: ["Male", "Female"]
        },
        birthday:{
            type: Date,
            label: "Date Of Birth",
            autoform: {
                type: "bootstrap-datepicker"
            }
        },
        address:{
            type: Object
        },
        'address.city':{
            type: String,
            label: "City/Province",
            max: 80
        },
        'address.state':{
            type: String,
            label: "State",
            max: 80
        },
        'address.country':{
            type: String,
            label: "Country",
            max: 80
        },
        /*privacy:{
            type: String,
            label: "Privacy",
            allowedValues: ["On", "Off"]
        }, */
        aboutYou:{
            type: String,
            label: "About You",
            autoform: {
                afFieldInput: {
                    type: "textarea"
                }
            },
            max: 400
        },
        socialNetworks:{
            type: Object,
            label: "Social Networks"
        },
        'socialNetworks.facebook':{
            type: String,
            label: "Facebook",
            autoform: {
                placeholder: 'Username'
            },
            max: 50
        },
        'socialNetworks.instagram':{
            type: String,
            label: "Instagram",
            autoform: {
                placeholder: 'Username'
            },
            max: 50
        },
        'socialNetworks.tumblr':{
            type: String,
            label: "Tumblr",
            autoform: {
                placeholder: 'Username'
            },
            max: 50
        },
        'socialNetworks.twitter':{
            type: String,
            label: "Twitter",
            autoform: {
                placeholder: 'Username'
            },
            max: 50
       }
    });
    
    Schema.User = new SimpleSchema({
        username: {
            type: String,
            regEx: /^[a-z0-9A-Z_]{3,15}$/,
            optional: true
        },
        emails: {
            type: [Object],
            // this must be optional if you also use other login services like facebook,
            // but if you use only accounts-password, then it can be required
            optional: true
        },
        "emails.$.address": {
            type: String,
            regEx: SimpleSchema.RegEx.Email
        },
        "emails.$.verified": {
            type: Boolean
        },
        createdAt: {
            type: Date
        },
        profile: {
            type: Schema.UserProfile,
            optional: true
        },
        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
        }
    });
    
    Meteor.users.attachSchema(Schema.User);
    

    For your allow and deny rules, you may want to makes sure that the userId matches the _id of the document instead of just seeing if they are logged in.

    Login or Signup to reply.
  2. Try this (search for “NOTE” for comments describing the relevant changes):

    Settings HTML:

    <template name="settings">
    <div class="text-center light-container" id="settings-section">
        {{! NOTE: the fields attribute tells quickForm which fields to display }}
        {{> quickForm collection="Meteor.users" fields="userProfile" doc=currentUser id="userProfile" type="update"}}
    </div>
    

    Settings JS In Both Directory

    Schema = {};
    
    Schema.UserProfile = new SimpleSchema({
        userProfile: {
            type: Object
        },
        'userProfile.firstName':{
            type: String,
            label: "First Name",
            max: 80
        },
        'userProfile.lastName':{
            type: String,
            label: "Last Name",
            max: 80
        },
        'userProfile.gender':{
            type: String,
            label: "Gender",
            allowedValues: ["Male", "Female"]
        },
        'userProfile.birthday':{
            type: Date,
            label: "Date Of Birth",
            autoform: {
                type: "bootstrap-datepicker"
            }
        },
        address:{
            type: Object
        },
        'address.city':{
            type: String,
            label: "City/Province",
            max: 80
        },
        'address.state':{
            type: String,
            label: "State",
            max: 80
        },
        'address.country':{
            type: String,
            label: "Country",
            max: 80
        },
        /*privacy:{
            type: String,
            label: "Privacy",
            allowedValues: ["On", "Off"]
        }, */
        aboutYou:{
            type: String,
            label: "About You",
            autoform: {
                afFieldInput: {
                    type: "textarea"
                }
            },
            max: 400
        },
        socialNetworks:{
            type: Object,
            label: "Social Networks"
        },
        'socialNetworks.facebook':{
            type: String,
            label: "Facebook",
            autoform: {
                placeholder: 'Username'
            },
            max: 50
        },
        'socialNetworks.instagram':{
            type: String,
            label: "Instagram",
            autoform: {
                placeholder: 'Username'
            },
            max: 50
        },
        'socialNetworks.tumblr':{
            type: String,
            label: "Tumblr",
            autoform: {
                placeholder: 'Username'
            },
            max: 50
        },
        'socialNetworks.twitter':{
            type: String,
            label: "Twitter",
            autoform: {
                placeholder: 'Username'
            },
            max: 50
        }
    });
    
    // NOTE: You need to use this schema because it is the schema for the collection you are updating.
    Schema.User = new SimpleSchema({
        username: {
            type: String,
            regEx: /^[a-z0-9A-Z_]{3,15}$/,
            optional: true
        },
        emails: {
            type: [Object],
            // this must be optional if you also use other login services like facebook,
            // but if you use only accounts-password, then it can be required
            optional: true
        },
        "emails.$.address": {
            type: String,
            regEx: SimpleSchema.RegEx.Email
        },
        "emails.$.verified": {
            type: Boolean
        },
        createdAt: {
            type: Date
        },
        profile: {
            type: Schema.UserProfile,
            optional: true
        },
        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
        }
    
        */
    }); 
    
    // NOTE: Meteor.users is a collection of objects matching the Schema.user schema, so you need to use this schema.
    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' field
            return !! userId && userId === doc._id && _.isEmpty(_.difference(fieldNames, ['userProfile'])); 
        },
        /* 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();
        }
        */
    });
    

    Settings JS in Client Directory

    /* NOTE: I don't think you need any of these hooks.
        var postHooks = {
            before: {
                insert: function(doc) {
                    if(Meteor.userId()){
                        doc.userId = Meteor.userId();
                    }
    
                    return doc;
                }
            },
            docToForm: function(doc) {
                if (_.isArray(doc.tags)) {
                    doc.tags = doc.tags.join(", ");
                }
                return doc;
            },
            formToDoc: function(doc) {
                if (typeof doc.tags === "string") {
                    doc.tags = doc.tags.split(",");
                }
                return doc;
            }
        };
    
        AutoForm.addHooks('UserProfile', postHooks);
    
    */
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search