I am trying to make profile page and, I need to display the profilename and bio to a template. The problem is I can't get the Id of each profile object. If I can get the Id of each profile like how it's done in the book with postId. Here The code below is the way I thought it would work but did not. If you tell me how to get the Id that would be great thanks.
Profile = new Meteor.Collection('profile');
Profile.allow({
update: ownsDocument
})
Profile.deny({
update: function(profileId, profile, fieldNames) {
return (_.without(fieldNames, 'bio').length > 0);
}
});
Accounts.onCreateUser(function(options, user){
Meteor.methods({
profile: function(postAttributes) {
var user = Meteor.user();
var profile = _.extend(_.pick(options.profile, 'bio'), {
userId: user._id,
profilename: user.username,
submitted: new Date().getTime(),
postsCount: 0, posts : []
});
var profileId = Profile.insert(profile);
return profileId;
}
});
return user;
});
In the discover meteor example, they are using a method to insert a Post and then return its id. In your case, a new Profile is being inserted inside of an asynchronous callback so there's no way for you to return the id. However, you know the userId, so you can use that to get the profile.
Server
Accounts.onCreateUser(function(options, user){
var user = Meteor.user();
var profile = _.extend(_.pick(options.profile, 'bio'), {
userId: user._id,
profilename: user.username,
submitted: new Date().getTime(),
postsCount: 0,
posts : []
});
Profile.insert(profile);
return user;
});
Client
Template.profile.profile = function () {
return Profiles.findOne({userId: Meteor.userId()});
};
You seem a little confused on some Meteor ideas.
Firstly Meteor.methods({ ... }) are functions that can be called client side using Meteor.call({ })
They should appear at the top level and not inside other functions like Accounts.onCreateUser
For this use case I don't see why you need a method at all though. All you want to do is retrieve data that you will be storing in data that is going to be sent to the client anyway.
If you use the accounts-base package then you automatically get a Meteor.users collection that would be fine for what you want to do. I don't see the need for a Profile collection
Here's a meteorpad illustrating it: http://meteorpad.com/pad/xL9C8eMpcwGs553YD
Note I store the bio in the profile section of the user. This is because a user can edit their own profile section by default and so I can do Meteor.users.update( ... ) client side.
This is just an example to show some of the concepts. It does have bad practice in it. For a start I would recommend adding the package accounts-ui and using the {{> loginButtons}} helper. It gives you the error checking and so on. The reason I didn't use it was because I wanted to show how to allow a user to enter their bio prior to creating the account and how you can use that in Accounts.onCreateUser.
Related
I'm trying to update/add data on firebase. I used the Facebook login and I want to use the UserID as a key for the new data aded.
(check pict below)
The userID that I want to use it:
I want to replace that key with the userID:
fblogin(){
this.facebook.login(['email'])
.then(res=> {
const fc = firebase.auth.FacebookAuthProvider.credential(res.authResponse.accessToken);
firebase.auth().signInWithCredential(fc)
.then(fs => {
this.facebook.api('me?fields=id,name,email,first_name,picture.width(720).height(720).as(picture_large)', []).then(profile => {
this.newuser = {name: profile['first_name'] ,email: profile['email'],picture: profile['picture_large']['data']['url'],phone:''}
this.navCtrl.push(HomePage);
console.log(fs.uid);
this.db.list('/users/'+ fs.uid).update(this.newuser);
});
I got this error in compilation:
supplied parameters do not matchany signature of call target
In this line: this.db.list('/users/'+ fs.uid).update(this.newuser);
Any help?
The FB error looks correct. You cant update on the uid as the user has been saved with a unique FB id
You do not show the code that created the users record in the database, but what i think you want to do is set and object when you first save the users record. However this could be an issue because the user could be saved before the return of the uid. I cant tell with your code snippet. Regardless, I will write the code that i think will work if the users/ record is created at the time that of registration.
The service
async signupUser(email: string, password: string) {
try {
const result = await this.afA.auth.createUserWithEmailAndPassword(email, password);
return result;
} catch (err) {
console.log('error', err);
}
}
So this initially creates a user without facebook, The key here is that the users FB uid was created and is held in the returned result
The component
this.authData.signupUser(email,password).then(userData => {
console.log(userData) // <- this is result
}
Then we create a record in FB with the uid returned
this.db.object(`users/${userData.uid}/`).set(data);
.set(data) is whatever data you want to save in the users/uid namespace.
So basically you need to create that user table with its uid namespace when the user first registers. Then you can update the user with the uid returned from the facebook fs.uid
With your current code you could find the user based on the email ( because the email should be unique to all users) and then update ...
with lodash is it just
let foundUser = find(this.db.list('users'),{ 'email' : fs.email }
// and then update based on the object key
this.db.list('/users/'+ Object.keys(foundUser)).update(this.newuser);
i fixed the problem by using:
this.db.object('/users/'+ fs.uid).update(this.newuser);
instead of :
this.db.list('/users/'+ fs.uid).update(this.newuser);
And it works correctly !
Thanks all for help.
I'm trying to create a page that shows all the users in the db that belong to my same organization.
My users are stored as follows:
Accounts.createUser({
email: email,
password: password,
profile:{
firstName: first,
lastName: last,
type: "Member",
organization: organization,
created: date
}
});
I know I have to publish the users to my user list component, and i'm struggling figuring out how to publish only the users whose profile.organization matches the logged in users profile.orgainzation.
This returns all users as it should, I got that far:
return Meteor.users.find();
I tried using the next block of code you see here, but it doesn't work, probably for multiple reasons, it even throws an error saying I can't use Meteor.user() server side, that I have to use this.user()... but that didn't work either:
return Meteor.users.find({
profile:{
organiztion: Meteor.user().profile.organization
}
});
I'm not sure where to go from here. Any help would be greatly appreciated!
I think this might work (untested). This is a server-side function.
Meteor.publish("organizationUsers", function () {
if (this.userId) {
var user = Meteor.users.findOne(this.userId);
var org = user.profile.organization;
return Meteor.users.find({'profile.organization': org});
}
});
Client side, you can filter the users you want (and exclude the current user) with:
Meteor.users.find({'profile.organization': org, '_id' : {$not : Meteor.userId()}});
I have a problem I can't find an answer to in Loopback's docs.
Say I have a model Company and a modelEmployee. There is an 1Xn relation between the Company and its Employees. When /api/Employees is called, server returns all the employees.
I only want to return the list of employees who are in the same company with the user requesting the list.
For this, I created a remote hook
Employee.beforeRemote('find', function(context, modelInstance, next) {
var reject = function() {
process.nextTick(function() {
next(null, false);
});
};
// do not allow anonymous users
var userId = context.req.accessToken.userId;
if (!userId) {
return reject();
}
//I get the details of the user who sent the request
//to learn which company does he belong to
Employee.findById(userId, function(err, user) {
if(!context.req.query.filter) context.req.query.filter={};
context.req.query.filter.where = {brandId:user.companyId};
console.log(context.req.query);
next();
});
});
I thought this should work every time, but appearantly it only works when find already has some query filters like include - although the console.log prints a correct context.req.query object.
What am I missing? Any help would be greatly appreciated!
context.args.filter seems to work for this purpose.
As a side note, instead of replacing where, you might want to merge it with something provided by client. For implementation idea you can refer to: https://github.com/strongloop/loopback-datasource-juggler/blob/master/lib/utils.js#L56-L122
I'm trying to use the Meteor Roles package: https://github.com/alanning/meteor-roles
to obviously create a new field in user model.
The user is created no problem but the 'roles' field I'm trying to define isn't created. I can add things like 'Profile' and details within that too. But for some reason I can't make a roles field. Here's my form:
Template.signup.events({
'submit #signup-form' : function(e, t) {
e.preventDefault();
var roles = ['admin'],
email = t.find('#email').value,
password = t.find('#password').value;
Accounts.createUser({email: email, password : password, roles: roles}, function(err){
if (err) {
alert("User Not Added")
} else {
console.log("User Added.")
}
});
}
});
Eventually I'll need to publish this to the client but for right now I just want the field to show in MongoDb, which it's not.
3 things:
I feel like the code above should work but I'm clearly missing something
In the package docs it mentions this Roles.addUsersToRoles which I
tried but no luck
Or do I need to possibly update the record, after it's been created?
I did go into the DB and manually added the field and associated string to update it (with $set) and it worked. But from the form itself though, no luck.
Any pointers would be much appreciated. Thank you.
The Accounts.createUser function only lets you add arbitrary user properties via the profile option which is where they end up getting stored in mongo. That is why Meteor is ignoring the roles: roles part of your Accounts.createUser call.
It is true that the meteor-roles package stores the list of roles assigned to a user directly in the users collection, but that is almost just an implementation detail and you are probably best off sticking to the API that meteor-roles provides for adding users to a role:
Roles.addUsersToRoles(<userId>,[<list of roles>])
The userId passed to Roles.addUsersToRoles is the value returned by Accounts.createUser when its called on the server which is probably where you want to be doing this as that feels way more secure.
The Accounts.createUser function only takes username, email, password and profile as params for the user object. See the documentation here. So, to add another field to a new user object, you need to add it in a second step:
var uid = Accounts.createUser({email: email, password: password});
Meteor.users.update(uid, {$set: {roles: roles}});
Like the questions asks, can this be done?
I would like to insert an array of a user's links into the current user's profile. I tried something like following on the client side but it did not work:
Meteor.users.update( {_id: Meteor.userId()}, {
$set: {
profile: {
userlinks: {
owned: "_entry_id"
}
}
}
});
I also tried replacing update with insert but to not avail.
I have a couple of suspicions about what it could be:
I am not setting the mongodb permissions correctly (least likely)
I am not publishing the user collection correctly (I currently don't publish it at all so I assume meteor does this automatic... but maybe not enough of it?) (somewhat likely)
Insert is the correct command but this is restricted to the server, so I have to put the insert function inside of a Meteor method on the server and then call that method from the client? (more likely)
Or maybe I just have no idea what I am talking about (most likely)
Check Meteor Update Docs your syntax is wrong.
Try:
var id = Meteor.userId();
Meteor.users.update( id, {
$set: {
profile: {
userlinks: {
owned: "_entry_id"
}
}
}
});
You can do that, your user needs to have a profile field to start with if you're using a custom account UI make sure you set the profile to something when you authenticate a user even if it's just a blank object to start with:
var options = {
username: 'some_user',
password: 'password',
email: 'email#domain.com',
profile: {}
}
Accounts.createUser(options, function(err){
if(err){
//do error handling
}
else
//success
});
if you've removed the insecure package you'll need to make sure you setup the Meteor.users.allow
something like:
Meteor.users.allow({
update: function(userId, doc, fieldNames, modifier){
if(userId === doc._id && fieldNames.count === 1 && fieldNames[0] === 'profile')
return true;
}
})
so that the user can only update themselves and they can only update the profile field.