How to remove logged in user in Meteor - javascript

I'm developing an app in Meteor and I want to know how I do can delete a user's account who is logged into the system? I mean that you can delete your account (like Tinder or Facebook) and the application ejects you because you're already deleted, and you no longer exist.
With a simple button of "Delete your account" attached.
If you could help me; I'm still a novice I'd really appreciate it, I try to retrieve the id of the current user with Meteor.userId(), and I was creating a method in the following way:
Meteor.methods({
SuprimirPersona: function(id) {
var postId = Meteor.userId();
const userId = this.userId;
const p = Meteor.users.findOne(postId);
if (userId && p === userId) {
Meteor.users.remove({
postId: this._id
},
function(error, result) {
if (error) {
console.log("Error removing user:", error);
} else {
console.log("users removed:" + result);
}
})
}
}
});
And calling the method in the following way but it does not give any results, I do not understand why:
'click #Desactivarr': function() {
var postId = Meteor.userId();
Meteor.call('SuprimirPersona', userId, function(error, result) {
if (error) {
console.log("Somee Error");
}
});
Meteor.logout(function() {
FlowRouter.go('/');
});
},
Hope someone could help me! Regards!

I've just answered this question on Meteor Forums:
https://forums.meteor.com/t/how-to-remove-logged-in-user-in-meteor/42639/3
The issue is you're trying to remove Users by postId, instead of Users.remove({_id: id}). You're removing nothing :)

To remove a user from the user's collection. You need to get the userid of the user you want to remove. This you can get by calling Meteor.userId() on the client to get the userid of the user or this.userId on the server. You need to logout the user and after a successful logout you can pass the userid you got to the meteor.users.remove(userId)

You are doing some unnecessary things on the client and server side - like getting the same user id multiple times, not even passing it to the server side method and then getting it again.
I think what you are trying to do is get the id of a user that posted something and pass it to the server side, where you check if the poster's id is the same as the id of the current user. If so, you remove the user, otherwise nothing happens.
'click #desactivarr' : function() {
var postID = <get the id of the user you want to delete here>;
Meteor.call("suprimirPersona", postID, callbackfunc);
}
Then on the server side it would be
Meteor.methods({
suprimirPersona : function(postID) {
var userID = Meteor.userId();
if (userID && postID === userID) {
Meteor.users.remove({ postId : userID })
}
}
});
Meteor.userId() and this.userId return the id of the currently logged in user that is executing the code on the client side or making the request to a server side method.

Related

How to make separate login for Users and Freelancer based on Roles that is in my real time database Firebase

Hello I am working a web application with Firebase Realtime Database and Authentication with nodejs or javascript.
This is my real time database and I want to make a login form which if the User = User he will go to User Index and if the User = Freelancer he will go to Freelancer Index.
And this is the line of code that I was tweaking or trying but It doesn't go in my way.
<script>
firebase.auth().onAuthStateChanged(function(user)
{
if(user)
{
var userID = firebase.auth().currentUser.uid;
firebase.database().ref('Users/' + userID).once('value').then(function(snapshot)
{
if (snapshot.val())
{
window.location.href = "index.html";
}
else
{
window.location.href = "okay.html";
}
});
}
});
</script>
Hoping I can get feedbacks or answers here. I am almost trying it for 2days already that's why I seek help here.
Comments and answers are highly appreciated thank you!
With your current data structure you will need to check in two places to determine what role a user has. While this technically possible, it is less efficient and more complex in code.
I recommend instead to store a single top-level node (say UserRoles) where you simply keep the role for each UID:
"UserRoles": {
"uidOfUser1": "Freelancer",
"uidOfUser2": "User"
}
With that in place, you can load it in your onAuthStateChanged callback with:
const ref = firebase.database.ref("UserRoles");
ref.child(user.uid).once("value").then((snapshot) => {
if (snapshot.val() === "Freelancer") {
window.location.href = "okay.html";
}
else if (snapshot.val() === "User") {
window.location.href = "index.html";
}
else {
alert("Can't determine role for user: "+user.uid)
}
});

Input Value doesn't save, when pushing onto array gives undefined value

I am trying to update the user account details in firebase but I have noticed that the input value for one of my fields keeps coming up as undefined even when I console.log it. I am working in two files one is a loginjs file in which I am defining the user input.
signUpForm.addEventListener('click', function (e) {
e.preventDefault();
isSigningUp = true;
var email = signUpEmailInput.value;
var password = signUpPasswordInput.value;
var displayNameUser = displayNameInput.value;
var userPrivateKey = signUpPrivateKey.value;
var user = firebase.auth().currentUser;
var photoURL = "https://www.gravatar.com/avatar/" + md5(email);
if (signUpPasswordInput.value !== signUpPasswordConfirmInput.value) {
setSignUpError('Passwords do not match!');
} else if (!displayNameUser) {
setSignUpError("Display Name is required!");
} else if (!userPrivateKey) {
setSignUpError('You need to set a Private Key!');
} else {
auth.createUserWithEmailAndPassword(email, password)
.then(function (user) {
user.updateProfile({
displayName: displayNameUser,
photoURL: photoURL,
privateKey: userPrivateKey
}).then(function () {
// Update successful.
window.location.href = 'chat.html';
}).catch(function (error) {
// An error happened.
window.alert("Some unexpected error happened!");
});
user.sendEmailVerification().then(function () {
// Email sent.
}).catch(function (error) {
// An error happened.
window.alert("Email was not able to send!");
});
})
.catch(function (error) {
// Display error messages
setSignUpError(error.message);
});
}});
The weird thing is that the user input for my displayname and photoURL are working just fine, but when it comes to my private key user input it registers the input when it goes to the chat page and I do a console.log(user.privatekey) It says it is undefined.
In my chatjs file, thats when I am pushing the all the user profile information. The chatjs file basically allows a user to send a message, the message and all the user profile information gets stored onto the firebase database.
messages.push({
displayName: displayName,
userId: userId,
pic: userPic,
text: myString.toString(),
privatekey: user.privatekey,
timestamp: new Date().getTime() // unix timestamp in milliseconds
})
.then(function () {
messageStuff.value = "";
})
.catch(function (error) {
windows.alert("Your message was not sent!");
messageStuff;
});
The thing again is that the privatekey does not get stored at all, which is what I am not understanding, since it is registering user input in the loginjs file but when I go to the chatjs file it keeps saying the value is undefiend. I have googled everywhere and I still haven't found a solution to it. Any help would be greatly appricated!
It's because the Firebase user object you receive from Firebase is not customizable. When you call the createUserWithEmailAndPassword(email, password) method, it returns a specifically defined user object back to you - check out the docs for the properties of this object.
The properties displayName and photoURL both work because they are already properties of the user returned. privateKey is not an existing property of the Firebase user object, and Firebase doesn't know how to handle an update call for a property that isn't defined. Check out this question & answer where Frank explains that Users in Firebase aren't customizable - you need to store any extra info separately.

Meteor: sending the document id via email

I have a newsletter which relies on meteor's email package.
As soon as an admin submits a new news & events entry to the collection, all subscribers receive this via email. This also works.
However, I want to have add the new concrete link of the news & events entry to the page.
The route for the news and events page:
// Specific news and events
Router.route('/news-and-events/:_id', {
name: 'newsAndEventsPage',
waitOn: function(){
return [
Meteor.subscribe('newsevents'),
Meteor.subscribe('images'),
Meteor.subscribe('categories'),
Meteor.subscribe('tags'),
]
},
data: function(){
return NewsEvents.findOne({_id: this.params._id});
},
});
The admin route (a form page) for adding a new entry:
// Admin news
Router.route('/admin-news-events', {
name: 'adminNewsEvents',
waitOn: function(){
return [
Meteor.subscribe('newsevents'),
Meteor.subscribe('images'),
]
},
data: function(){
return false
},
});
After submitting the post to the collection, I tried to catch the entry and pass the id, but I just get undefined.
My admin template.js (edited):
'submit form': function (evt, template) {
evt.preventDefault();
var temp = {};
temp.title = $('#title').val();
temp.description = $('#description').summernote('code');
temp.type = $('input[name=netype]:checked').val();
temp.createdAt = moment().format('ddd, DD MMM YYYY hh:mm:ss ZZ');
Meteor.call('NewsEvents.insert', temp);
Bert.alert("New entry added.");
//Fire the email to all Subscribers
var entry = NewsEvents.findOne(this._id);
var entryId = entry.id;
//NOT WORKING
var news = '<a href='+Meteor.absoluteUrl()+'news-and-events/'+entryId+'></a>';
for (i = 0; i < Subscribers.find().count(); i++) {
var email_ = Subscribers.find().fetch()[i].email;
Meteor.call('sendEmail',
email_, //To
'Open Strategy Network <xxx.yyy#zzz.yyy.xx>', //from
'Open Strategy Network News and Events', //subject
news);
}
}
Server methods:
Meteor.methods({
'NewsEvents.insert': function (doc) {
if (this.userId) {
NewsEvents.insert(doc);
}
}
});
...
//Send emails
'sendEmail': function (to, from, subject, text) {
// check([to, from, subject, text], [String]);
this.unblock();
Email.send({
to: to,
from: from,
subject: subject,
html: text
});
},
Thanks a lot.
.find() returns a cursor, not an object. You can either do:
var entry = NewsEvents.findOne(this._id);
var entryId = entry.id;
Or more simply since you already have the _id:
var entryId = this._id;
Or even more simply:
var news = '<a style:"text-decoration: none;"
href='Meteor.absoluteUrl()+'news-and-events/'+this._id+'></a>';
Also, you are trying to send the email while your insert is happening asynchronously.
Meteor.call('NewsEvents.insert', temp); // this might take some time to complete
var entry = NewsEvents.findOne(this._id); // `this` is not going to refer to the just added NewsEvent
Instead, do the notifications in a callback from the method:
Meteor.call('NewsEvents.insert', temp, function(err, result){
if ( !err ){
// assuming that `result` will be the _id of the inserted object!!
var news = '<a href='+Meteor.absoluteUrl()+'news-and-events/'+result+'></a>';
Subscribers.find().forEach(function(s){
Meteor.call('sendEmail',
s.email, //To
'Open Strategy Network <violetta.splitter#business.uzh.ch>', //from
'Open Strategy Network News and Events', //subject
news
);
}
}
});
Your NewsEvents.insert method needs to return the _id of the inserted object:
Meteor.methods({
'NewsEvents.insert'(doc) {
if (this.userId) return NewsEvents.insert(doc);
}
});
Now, even the above will be slow since you're doing Meteor.call() in a loop. Secondly, you've opened up your server as a mail relay since anyone can use the sendEmail method to send any email to anyone from the console inside your app. If you want to do this efficiently, put the notification code inside your NewsEvents.insert method and do it all on the server without all the back and forth!!
If I understood correctly, you want to have ID of the inserted document. Its fairly simple.
In the method that inserts:
var docId = Somethings.insert({ //fields here });
Now you can use that docId in the same method for sending emails.
If you also want to send the documentId to the client side, you can use error, result in Meteor.call() like this:
Meteor.call('methodName', arg, arg2, function(err, res){
if(!err){
//do something with res. in this case the res is inserted docId as I returned docId in the method
Router.go('/some-route/' + docId)
} else {
//do something with err
}
});
The error above comes from errors you throw in methods. For the result, you need to return a value which can be the inserted docId:
return docId
Tidied up method:
methodName: function (arg, arg2){
//equals to err in the `Meteor.call()`
if(arg !== 'something'){
throw new Meteor.Error('This is an error')
}
//insert new document
var docId = Somethings.insert({
fieldOne: arg,
fieldTwo: arg2
});
//send email to each subscriber. I don't know your exact DB fields so, its up to you. You did this in a different call.
var cursor = Subscribers.find();
cursor.forEach(function(ss){
//send email here. You can use each subscriber data like ss._id or ss.email. However you insert them...
});
//Equals to res in `Meteor.call()`. sends a result to the client side method call. inserted docId in this case
return docId
},
PS: If this doesn't answer you question, that means I didn't understand what you're trying to achieve exactly. Leave me a comment and I'll edit the answer.
EDIT
I used one method for both sending emails and inserting the document but still, you can pass error/result exactly like how I did and then do another call for emails using the id in result.

How to addUniqueObject to non-current user class using cloud code in Parse.com?

I want to add an array of current user object ID in to a user's column called "followers". Due to Parse's security reason not allowing modification to non-current user, I'm forced to use cloud code. The problem is I know nothing about JavaScript, so I need help here.
Here's what I would code if no security issue mentioned above:
//add the current user ID to the user(userPassed) that the current user liked
[userPassed addUniqueObject:[PFUser currentUser].objectId forKey:#"followers"];
[userPassed saveInBackground];
To be very specific, I just want to know how to code the above in cloud code. Thanks.
Here you go:
Parse.Cloud.define('functionName', function(request, response) {
var userId = request.params.userId;
var me = Parse.User.current();
var user = new Parse.User();
user.id = userId;
user.addUnique('followers', me);
return user.save(null, {useMasterKey: true}).then(function(user) {
response.success('Succeed');
}, function(error) {
console.error(error);
response.error('Failed');
});
});

how to get current user on firebase

I would like to know how how to get the current user. I am making a function where the user is creating a group and would like to add the user making the group to it at the same time. I can make the group fine, that was simple enough. But I do not know how to get to the user object outside of the simple login object.
I'm sorry if there are several topics stating this already, but I have been looking for hours and have not been able to find anything that explains it. Any help would be appreciated.
The currently logged in user is returned from Simple Login's callback. This callback runs when your user authenticates, or if your user is already authenticated, it runs at the time of page load.
Take this code form the simple login docs:
var myRef = new Firebase("https://<your-firebase>.firebaseio.com");
var authClient = new FirebaseSimpleLogin(myRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
console.log("User ID: " + user.uid + ", Provider: " + user.provider);
} else {
// user is logged out
}
});
The user object is exposed in the callback. It's only in scope during the execution of that callback, so if you want to use it outside, store it in a variable for reuse later like this:
var currentUser = {};
var myRef = new Firebase("https://<your-firebase>.firebaseio.com");
var authClient = new FirebaseSimpleLogin(myRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
currentUser = user;
} else {
// user is logged out
}
});
...
// Later on in your code (that runs some time after that login callback fires)
console.log("User ID: " + currentUser.uid + ", Provider: " + currentUser.provider);

Categories