Problem for displaying the user's profile data


#1

Hello, I’ve created a collection to store additional info of the user, the info is successfully inserted in the collection but when I want to display it, it doesn’t appear and I can’t seem to find the problem.

Here’s my Profiles collection

export const Profiles = new Mongo.Collection('profiles');

const ProfileSchema = new SimpleSchema({
    Age: {
        type: Number,
        label: "Edad",
        optional: true
    },
    Job: {
        type: String,
        label: "Trabajo",
        optional: true
    },
    Phone: {
        type: Number,
        label: "Telefono",
        optional: true
    },
    Address: {
        type: String,
        label: "Direccion",
        optional: true
    },
    Gender: {
        type: String,
        label: "Genero",
        optional: true
    },
    City: {
        type: String,
        label: "Ciudad",
        optional: true
    },
    SecurityNumber: {
        type: Number,
        label: "Cedula",
        optional: true
    },
    HealthInsurance: {
        type: Number,
        label: "Seguro medico",
        optional: true
    },
    Rnc: {
        type: String,
        label: "Rnc",
        optional: true
    },
    Exequatur: {
        type: Number,
        label: "Exequatur",
        optional: true
    },
    BirthDate: {
        type: Date,
        label: "Fecha de nacimiento",
        optional: true
    },
});

Profiles.attachSchema(ProfileSchema);

Profiles.allow({
    insert: function () {
        return true;
    },
    update: function () {
        return true;
    },
    remove: function () {
        return true;
    }
});

The event for inserting the data:

Template.Profile.events({
    "submit #profile-update": function (evt) {
        evt.preventDefault();
        var age = evt.target.age.value;
        var phone = evt.target.phone.value;
        var job = evt.target.job.value;
        var bday = evt.target.bday.value;
        var city = evt.target.city.value;
        var hi = evt.target.hi.value;
        var sn = evt.target.sn.value;

        if(Meteor.user){
            Profiles.insert({
                _id: Meteor.user()._id,
                Age: age,
                Phone: phone,
                Job: job,
                BirthDate: bday,
                City: city,
                HealthInsurance: hi,
                SecurityNumber: sn
            });
            Bert.alert('Edicion exitosa', 'danger', 'growl-top-right');
        }
    },
    'change .PicInput': function(evt, template){
        FS.Utility.eachFile(evt, function(file){
            Images.insert(file, function(err, fileObj){
                if(err){
                    throw new error(err.reason, "danger", "growl-top-right")
                }else{
                    var userId = Meteor.user()._id;
                    var imageURL = {
                        "profile.image": "/cfs/files/images/" + fileObj._id
                    };
                    Meteor.users.update(userId, {$set: imageURL});
                }
            })
        });
    }
});

And the helper

Template.Profile.helpers({
    UserInfo: function (info) {
        if (Meteor.user) {
            return Profiles.find({});
        }
    },
    images: function() {
        if(Meteor.user){
            return Images.find({});
        }
    }
});

Also I don’t know if is this is important but I’m using oncreateuser to modify the user’s initial data while signing up

   /**To modify the user's data */
    Accounts.onCreateUser(function (options, user) {

        if (!user.profile) {
            user.profile = {};
        }
        user.profile.firstname = options.firstname;
        user.profile.secondname = options.secondname;
        user.profile.surname = options.surname;
        user.profile.lastname = options.lastname;
        user.profile.email = options.email;

        AssignRole(options, user); //ignore this

        return user;
    });

I have subscribe to the profiles collection on the client side and published on the server side too:

Meteor.publish('profiles', function () {
    return Meteor.users.find({}) && Profiles.find({});
})

#2

I don’t think this does what you think it does. Your publication returns a boolean value instead of a cursor. In case you want to subscribe to more than one collection, your publication needs to return an array of cursors (which is what find returns).

I strongly recommend not to return Meteor.users.find() because that would publish all users, which is unnecessary and insecure. Same goes for Profiles.find(), why would you publish all Profiles, instead of just the profile of the current user?


#3

Well in another section of my web app I intend to show all of the users that have signed up, but since you said it is insecure what would be a safer route to do it? With the profiles, I’m just testing to see if it works and that’s it, I’m still new to meteor sorry about that. Also there’s another problem that the server displays to me and that is Exception from sub profiles id FMDDvKbnuhSrvgpQM ReferenceError: Profiles is not defined, that error has appeared with different Ids and been trying to figure out the problem for two days and I’m unable to find an answer.

Thanks in advance and thank you for clarifying that error.


#4

Well managing profiles is actually much simpeler, because there is a profile field in your users collection. You could just use Meteor.user().

I will give an example tomorrow, because its Xmass and fanily stuff etc… haha

Merry christmass! :rofl:


#5

:joy: :joy: :joy: Merry Christmas to you too and thanks a lot, but I have seen a few people say that it’s not recommended to use the profile field in the users collection for security reasons and since I need a lot of fields in the profiles collection I thought it would be better to create a profile collection of my own.


#6

Ah well, it just depends on how you use the profile fields. I think that recommendation was not about using the profile field as part of the user collection, but about putting private information into the profile field. This is because the profile field is always published to the logged in user.

If you require a separate profile collection, because of reasons (I can’t know them ofcourse) I would suggest publishing them based on the logged in userId:

Meteor.publish('profile', function() {
  const { userId } = this;

  if(userId) {
    return Profiles.find({ userId });
  }
});