0

I am using CollectionFs to Upload profile pictures. Uploading and storing the image is successful. I can insert and show the image alright for one user but the problem is: For multiple users, when a user visit other users profiles, He sees his own picture rather than seeing the profile owner's picture!

I understand its the mongo query I have in my helper function thats causing the issue but can't just get it to work no matter how many "This._id" I Try.

Here is the javaScript

 Router.route('show',{
  path:'/list/:_id',
  data: function(){
return Main_database.findOne({_id: this.params._id});


  }

});

 Template.upload.events({
  'change #exampleInput':function(event, template){  
    var file = $('#exampleInput').get(0).files[0]; 
    fsFile = new FS.File(file);
    fsFile.metadata = {ownerId:Meteor.userId()}
    Images.insert(fsFile,function(err,result){
      if(!err){
        console.log("New images inserted")
      }
    })
  }
});

Template.profile.helpers({
    profilePic: function () {
      return Images.find({'metadata.ownerId':Meteor.userId()});
    }
  });

And here is the html:

<template name="upload">
  <div class="container">
     <div class="row">
        <input type="file" 
        id="exampleInput"> 
     </div>  
  </div>
</template>


 
<template name="profile">

       {{#each profilePic}}       
          <img src="{{this.url}}" 
          height="400" width="400" 
          class="img-circle">
       {{/each}}  
 
</template>
Thanks

B.s : after following the answer given, I attached the photo in the profile.xxx field. But its still showing the wrong picture. The mongo query is still showing the wrong picture.

here is the code,

Router.route('show',{
  path:'/list/:_id',
  data: function(){
return Main_database.findOne({_id: this.params._id});


  }

});

Template.upload.events({
  'change #exampleInput':function(event, template){  
    var file = $('#exampleInput').get(0).files[0]; 
    newFile = new FS.File(file);
    newFile.metadata = {'ownerId':Meteor.userId()};
    Images.insert(newFile,function(err,result){
      if(!err){
        console.log(result._id);
        Meteor.users.update(Meteor.userId(),{
       $set: {
         'profile.profilePic': result._id

       }
     });
       }
     });

      }
    })



// .....................profile pic.............


Template.profile.helpers({
    profilePicture: function () {
      return Images.find({'_id':Meteor.user().profile.profilePic});
    }
  });
Cœur
  • 37,241
  • 25
  • 195
  • 267
Kaiyes
  • 33
  • 8

3 Answers3

1

Finally was able to do it. Being a beginner, I was stuck at uploading images and then showing them for my users for days. Tried almost each method out there, none worked. asked everywhere, none of the answer worked. Finally , a dead simple package from cosio55:autoform-cloudinary worked like magic!!! Just take a look at the problems I faced while using these packages:

1. cfs:ui

{{#with FS.GetFile "images" selectedImageId}} // image url {{/with}}

problem:

with this was I couldn't get the selectedImageId .

2. cfs:gridfs

problem :

grid fs stores image in a separate collection. My user list uses iron router to show the user list form another collection. Image was getting uploaded into the images collection. But For the love of my life, I couldn't show them correctly. Each user was seeing his own picture rather than the profile owner's picture. happened because of a wrong mongo query but I couldn't get the right query. Tried attaching the photo in the profile.profilePicture, but same problem of wrong image stayed.

And I had to put the upload photo in a separate page and NOT in the autoform.

3. lepozepo:cloudinary Problem: Image uploaded fine. But had problem getting /storing the image url. Couldn't get

And I had to put the upload photo in a separate page and NOT in the autoform.

public_id ????? Got lost there.

4. autoform-file by yogiben

same problem as GridFs.

Finally with this cosio55:autoform-cloudinarypackage took me just a minute to figure things out. A minute vs days of other big name packages!!!!

:smiley:

<div> <img src=" {{image}}" alt=""> Image </div>

just add {{image} in the img source and thats it. The image url is stored in the same collection autoform stores everything.

Cheers Mates.

Kaiyes
  • 33
  • 8
0

For the profilePic it will return the same user profile image, instead you should do a query by _id and not metadata.ownerId

To do that you should have a reference for the image in users collection when you insert the image something like:

Images.insert(file, function (err, res) {
  if (!err) {
     Meteor.users.update(Meteor.userId(),{
       $set: {
         'profile.profilePic': res._id,
       }
     });
});

And when you need to display the image you can do something like:

Template.profile.helpers({
    profilePic: function () {
      return Images.find({'_id':Meteor.user().profile.profilePic});
    }
 });
Mabed
  • 81
  • 3
  • check Meteor.users.allow or Meteor.users.deny roles – Mabed Sep 23 '15 at 01:05
  • Hi, I was able to use the update method, and store the res._id in the users profile. But still the problem remains. When a logged in user tries to view other people's profile, he still sees his own profile picture – Kaiyes Sep 27 '15 at 05:55
0

First things first: Meteor.user() and Meteor.userId() always shows data for CURRENTLY logged-in user.

So when user wants to see his own profile, it is right to use your current Template helper like this:

Template.profile.helpers({
    profilePic: function () {
        return Images.find({'metadata.ownerId':Meteor.userId()});
    }
});

But when user goes to another user's profile, you should fetch that user's info like this: Meteor.user("another-user-id");

So how to do this? Let's suppose that you have set routing in you Meteor app with Iron Router or Flow Router and for user profile page you have set-up route path something like this: /user/:_id.

Now, you want to publish only this user's data like this in your publications on the server:

Meteor.publish("userData", function(userId){
    return = Meteor.users.find({"_id": userId});
});

...and subscribe to this publication on client (we'll use Template-level subscriptions!)

  1. With Iron Router:

    var userId;
    
    Template.profile.onCreated(function() {
        var self = this;
        self.autorun(function() {
            userId = Router.current().params._id;
            self.subscribe("userData", userId);
        }
    });
    
    Template.profile.helpers({
        profilePic: function () {
            return Images.find({'metadata.ownerId': userId});
        }
    });
    
  2. With FlowRouter:

    var userId;
    
    Template.profile.onCreated(function() {
        var self = this;
        self.autorun(function() {
            userId = FlowRouter.getParam("_id");
            self.subscribe("userData", userId);
        }
    });
    
    Template.profile.helpers({
        profilePic: function () {
            return Images.find({'metadata.ownerId': userId});
        }
    });
    
Michal Takac
  • 37
  • 1
  • 6
  • `Router.route('show',{ path:'/list/:_id', data: function(){ return Main_database.findOne({_id: this.params._id}); } });` @Michal Takac I already have this route function for getting the data from my main user database which is separate from the Images database. So two route function is what I am looking for right? – Kaiyes Sep 30 '15 at 06:15