Meteor: How to keep showing profile avatar after logged out? - meteor

After reading Discover Meteor, I'm trying to customize microscope to further practice my meteor skills.
I am using accounts-twitter and hope to display the user's twitter profile pic on each of their post submission. I user the following helper to get the post's author id in post_item.js
Template.postItem.helpers({
username: function () {
owner = this.userId;
var user = Meteor.users.findOne({
_id: owner
});
return user;
}
});
And then in post_item.html I use the following to display the profile pic:
<img class="pull-right" src="{{username.profile.avatar}}">
If I've logged in my account, I can see my profile pic next to all of my submitted posts. However, when I log out, all the profile pics will be disappeared.
Sorry for the newbie questions. Any pointers are welcome.
Thanks for your help.

Stupid me. I forgot that by default, Meteor only publishes the logged in user. Hopefully the following answer will help other meteor newbies.
Server:
Meteor.publish("allUsers", function () {
return Meteor.users.find({}, {
fields: {
profile: 1
}
});
});
Client:
Meteor.subscribe('allUsers');
Then you will be able to load all the user's profile pics using the following:
<img src="{{username.profile.avatar}}">

Related

How do I login a user with Meteor

I've added accounts-password and useraccounts:unstyled
I've included the signin template in my footer.html -
{{#if showSignIn}}
{{> atForm state="signIn"}}
{{/if}}
I'm hard coding the creation of users as the app starts up -
import { Accounts } from 'meteor/accounts-base'
if (!Acounts.findUserByEmail('aidan#gmail.com')) {
Accounts.createUser({
username: 'Aidan',
email: 'aidan#gmail.com',
password: 'securePassword'
});
}
It's just that I can't work out how to actually log my user in. I've tried simply entering the password and email address into the form. That doesn't work (the form error says 'Login Forbidden').
I've tried adding the following line (to the same file as my account creation code) -
accountsServer.validateLoginAttempt(()=>{return true;});
Unsurprisingly that doesn't do anything.
I've tried add a submit event into my footer.js file -
Template.footer.events({
'submit form'(event) {
console.log('submitted');
const email = document.getElementById('at-field-email').value;
const password = document.getElementById('at-field-password').value;
Meteor.loginWithPassword(email, password);
},
});
I can see that the event is firing, but when I try Meteor.user() in the console I still get null.
There's typo in if (!Acounts.findUserByEmail('aidan#gmail.com')) (it should have been Accounts). The user isn't being created.
To get a super simple functional login with a single hard coded user -
Add the accounts-password package and the ui user accounts package.
> meteor add accounts-password
> meteor add useraccouts:unstyled
The accounts-password package handles the actual logging in. The user accounts:unstyled packages provides a set of templates for accounts management.
Then add the login form to a template.
<template name="templateWithLogin">
{{> atForm state="signIn"}}
</template>
Lastly create a user (e.g. in /server/main.js).
import { Accounts } from 'meteor/accounts-base';
if (!Accounts.findUserByEmail('user#gmail.com')) {
Accounts.createUser({
username: 'User',
email: 'user#gmail.com',
password: 'securePassword'
});
}
This should be everything needed to get a functional login form. There's loads of tutorials online for creating additional functionality. The main documentation is here.
you can use {{>loginButtons}} to get the ui and {{#if currentUser }} for the functionality.

How to show correct profile picture Meteorjs

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});
}
});
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.
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});
}
});
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!)
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});
}
});
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});
}
});

How to delete users from account-ui meteor

I'm making a meteor app and using accounts ui and bootstrap and all that stuff but I'm wondering if there is a way I can be like an admin and delete users because recently people have been making inappropriate usernames and such..
Well you can delete users pretty easy like. having a template protected just to admin accounts and on that template have a list with the users, based on that create an event like this.
Template.example.events({
'click #deleteAccount':function(){
meteor.users.remove({_id:this._id})
}
})
and use an allow method like this.
Meteor.allow({
remove:function(){
//if is admin return true;
}
})
But thats not a good practice, why? check this David Weldon -common-mistakes
if there is a way I can be like an admin?
For accomplish this on a better way use the meteor-roles package,
With this you can can protect templates with
{{if isInRole 'Admin'}}
<!--show admin stuff-->
{{else}}
<!--sorry just admin stuff here -->
{{/else}}
and create basic admin accounts.
if(Meteor.users.find().count() === 0){
var users = [
{name:"Admin Example",email:"supersecretaccount#gmail.com",roles:['Admin']}
];
_.each(users, function (user) {
var id;
id = Accounts.createUser({
email: user.email,
password: "amore251327",
profile: { name: user.name }
});
if (user.roles.length > 0) {
Roles.addUsersToRoles(id, user.roles);
}
});
}
Try it

Publishing all Meteor.users doesn't work

I'm trying to publish all the usernames to the clients, even if not signed in. For that, on the server I have:
Meteor.publish("users", function() {
return Meteor.users.find({}, {fields : { username : 1 } });
});
And on the client:
Meteor.subscribe("users");
However, when I try to access the Meteor.users collection, I find nothing there.
(This is essentially the same as the question here: Listing of all users in the users collection not working first time with meteor js, only without checking the roles for admin first. Still doesn't seem to work..)
I'm probably missing something silly..
I find the same issue, and after doing a research i find this package, i think it may should help you.
Take a look and hope it help you
Update
First move the subscription to the /lib folder, just to make sure its the first thing meteor do when start, also change a little bit the subscription like this on the /lib, folder.
Tracker.autorun(function() {
if(Meteor.isClient) {
if (!Meteor.user()) {
console.log("sorry you need to be logged in to subscribe this collection")
}else{
Meteor.subscribe('users');
}
}
});
For better security we just subscribe to the users collection when the client its logged in
This code outputs all the usernames to the clients, even if not signed in (in this case on /users page):
server/publications.js:
Meteor.publish("userlist", function () {
return Meteor.users.find({},{fields:{username:1}});
});
client/users_list.js:
Template.usersList.helpers({
users: function () {
return Meteor.users.find();
}
});
client/users_list.html:
<template name="usersList">
{{#each users}}
{{username}}
{{/each}}
</template>
lib/router.js (using iron:router package):
Router.route('/users', {
name: 'usersList',
waitOn: function(){
return Meteor.subscribe("userlist");
}
});
Hope it helps.

linkedin public profile url memberdata plugin

I am trying to create a company directory which will provide a link to an employees linkedin public profile, if the uses chooses to connect.
So on our employee profile page, the user can choose to link their linkedin account to their employee profile. We initiate an oAuth process and we retrieve their hashed linkedin id, which we then store. Great. Now the part that isn't working.
Based on their plugin example, i have this...
<script type="text/javascript" src="http://platform.linkedin.com/in.js">
api_key: xxxxxxxxxxxx
authorize: false
</script>
<script type="text/javascript">
function INTEST() {
IN.API.Profile().ids("pU-LBvD_y0")
.fields(['id', 'firstName', 'lastName', 'picture-url', 'public-profile-url'])
.result(function (result) {
profile = result.values[0];
})
.error(function (errorResult) {
var i = 0;
});;
}
</script>
I receive all information except the public-profile-url.
Any help would be greatly appreciated.
I'm sure you have this figured out by now. But for the benefit of others:
When using the JavaScript API you must convert the profile field names from the dashed notation to studly caps. For example first-name becomes firstName. public-profile-url becomes publicProfileUrl
Reference the following API documentation at
http://developer.linkedinlabs.com/tutorials/jsapi_profile/

Resources