Cloud Code Not Updating User's Username Properly - javascript

For some reason Cloud Code isn't updating the current user's username, even though it is updating the email field. I'm using the master key, and although everything returns success, the username doesn't update (even on the data browser).
Here's my code:
//Get Current User
var user = Parse.User.current();
//Update username
user.set("email", request.params.email);
user.set("username", request.params.username);
user.save(null, {
//Success
success: function(user) {
//Done
response.success("Username saved! 🎉");
},
//Error
error: function(user, error) {
// Execute any logic that should take place if the save fails.
response.error("Aww man. Something went wrong. Please try again. 😅");
}
});
I've made sure that the parameters are being passed correctly, and that there isn't a mistake with the name etc on my iOS app.

My guess is that there is an issue with getting the calling user.
Use request.user to get the calling user and try the following.
// Get the requesting user
var user = request.user;
if (user) {
user.set("email", request.params.email);
user.set("username", request.params.username);
user.save(null, {
success: function(user) {
response.success("Username saved! 🎉");
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
} else {
response.error("Aww man. Something went wrong. Please try again. 😅");
}

Related

ParseError: 'bad or missing username'

So I have some cloud code I am trying to write to like a post.
My database is setup that users have a likedPosts array, which has object id's of all the posts that the user liked. Users also have a column coins, that should get incremented when users like their posts.
The post object has a likes column which is an integer that gets incremented with each like, and the post object also has a posterId column, which is the object id of the user that posted it.
Here is my function right now (I am not very good at javascript and cloud code, so if there is something horribly wrong, I'm sorry)
Parse.Cloud.define("likePost", function(request, response) {
Parse.Cloud.useMasterKey();
var senderId = request.params.senderId;
var postId = request.params.postId;
var post = new Parse.Object ({objectId: postId});
var posterId = post.posterId
var poster = new Parse.User ({objectId: posterId});
var sender = new Parse.User ({objectId: senderId});
sender.add("likedPosts", postId);
poster.increment("coins");
post.increment("likes");
poster.save(null, {useMasterKey:true, success:
function(poster) {
console.log("Successfully saved poster");
}, error: function(poster, error) {
console.error("Error saving poster: " + error.message);
response.error(error);
}
});
post.save(null,{useMasterKey:true, success:
function(post) {
console.log("Successfully saved post");
}, error: function(post, error) {
console.error("Error saving post: " + error.message);
response.error(error);
}
});
sender.save(null, {useMasterKey:true, success:
function(sender) {
console.log("Successfully saved sender");
}, error: function(sender, error) {
console.error("Error saving sender: " + error.message);
response.error(error);
}
});
response.success();
});
I call the function from swift like so:
PFCloud.callFunction(inBackground: "likePost", withParameters: ["senderId" : PFUser.current()!.objectId!, " postId": postObject!.objectId!], block: { (result, error) in
if (error != nil) {
print(error!)
} else {
print("success liking")
}
})
In my logs, however, I get the following error:
2017-06-21T21:47:59.499Z - Failed running cloud function likePost for user R4d8Zrcdhw with:
Input: {"senderId":"R4d8Zrcdhw"," postId":"XXbu55PdpR"}
Error: {"code":141,"message":{"code":200,"message":"bad or missing username"}}
2017-06-21T21:47:59.492Z - bad or missing username
My guess is that the request is missing a header to define the content-type. I've seen Parse return the "bad or missing username" error via the Parse REST API if the Swift URLSession was using an incorrect content-type header.
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
or
Parse.Cloud.httpRequest({
url: 'http://www.example.com/',
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
})

How to sign up user and then keep them signed in and access current user Parse Server?

I am trying to get a user to sign up, I have the HTML form working etc. I just need to handle the sign up itself.
The user is successfully created BUT I'm not sure how to keep the user logged in or access the current user logged in as a Parse.User object.
app.post("/sign-up", function (req, res) {
var userObject = new Parse.User();
userObject.set("username", username);
userObject.set("password", password);
userObject.set("email", email);
userObject.set("supportEmail", email);
userObject.signUp(null, {success: function(user) {
//success
res.redirect('/admin');
},
error: function(user, error) {
//show error
console.log(error.message);
res.render('sign-up', {success:false, errorMessage:error.message});
}
});
});
Not sure what to do in order to keep them logged in and to acess the Parse.User object for the current user.
you can save in global variable in your application. also you can export user object to use in other files. There is another way to store in database or one other way is to app.locals.user = userObject
var userObject = new Parse.User();
app.post("/sign-up", function (req, res) {
userObject.set("username", username);
userObject.set("password", password);
userObject.set("email", email);
userObject.set("supportEmail", email);
app.locals.user = userObject;
userObject.signUp(null, {success: function(user) {
//success
res.redirect('/admin');
},
error: function(user, error) {
//show error
console.log(error.message);
res.render('sign-up', {success:false, errorMessage:error.message});
}
});
module.exports.userObject = userObjetct;
The signup promise resolves in an authentication object along with the session token.
Then you can use it and call Parse.User.become to retrieve the user class.
Parse.User.become("session-token-here").then(function (user) {
// The current user is now set to user.
}, function (error) {
// The token could not be validated.
});
Source: http://parseplatform.github.io/docs/js/guide/#setting-the-current-user

parse.com user.signup fails with error

Below is my code to signup for a new user
var Account = Parse.Object.extend('Account');
account = new Account();
account.set("serviceTax", TAX.SERVICE_TAX);
account.set("educationCess", TAX.EDUCATION_CESS);
account.set("name", accountName);
var user = new Parse.User();
user.set(USER.USER_NAME, username);
user.set(USER.PASSWORD, password);
user.set(USER.EMAIL, username);
user.set(USER.FIRST_NAME, firstName);
user.set(USER.LAST_NAME, lastName);
user.set(USER.PHONE_NUMBER, phoneNumber);
user.set(USER.COMPANY_NAME, companyName);
user.set(USER.ACCOUNT_NAME, accountName);
user.set(USER.ACCOUNT, account);
user.signUp(null, {
success : function(user) {
$('.gifload').toggle();
bootstrap_alert.info("alert_placeholder", "User created successfully");
},
error : function(user, error) {
$('.gifload').toggle();
bootstrap_alert.error("alert_placeholder", error.message);
}
});
I am getting the following error in this signup "user objects cannot allow writes from other users"
Now as far i can tell, we are not updating any user, just creating one with an account object. Why am i getting this error? Any help on this will be deeply appreciated.

Parse.com Cloud code Error: success/error was not called when trying to update a user

ive never used cloud code/javascript and I am trying to write some parse cloud code to find a user using a objectId passed in to the cloud function, and then update that users relation that holds friends and finally save that user.
below is the function im using:
Parse.Cloud.define("addFriendToFriendsRelation", function(request, response) {
Parse.Cloud.useMasterKey();
var fromUserObjectId = request.params.fromUserObjectId;
var acceptingUser = request.params.user;
var query = new Parse.Query(Parse.User);
// find the user the request was from using the objectId
query.get(fromUserObjectId, {
success: function(user) {
var fromUser = user
var relation = fromUser.relation("friends");
relation.add(acceptingUser);
fromUser.save({
success: function() {
response.success("Successfully saved the users relation")
},
error: function() {
response.error("Save failed");
}
});
},
error: function() {
response.error("Save failed");
}
});
});
I managed to piece this together using the Parse docs. but Im really not following it to well. Never used javascript and am finding the syntax confusing.
then im calling the function with
//fromUser is a PFUser object defined further up
[PFCloud callFunctionInBackground:#"addFriendToFriendsRelation" withParameters:#{#"fromUserObjectId" : fromUser.objectId} block:^(id object, NSError *error) {
}
however whenever this function is called I get a success/error was not called error. Though im calling response.success and response.error in the function so I dont know why that is? Can anyone lend a hand?
edit: after doing some more searching it looks like response.success and response.error should only be called once each, so I modified my function to look like this:
arse.Cloud.define("addFriendToFriendsRelation", function(request, response) {
Parse.Cloud.useMasterKey();
var fromUserId = request.params.fromUserObjectId;
console.log("fromUserId:");
console.log(fromUserId);
var acceptingUser = request.params.user;
console.log("acceptingUser:")
console.log(acceptingUser);
var query = new Parse.Query(Parse.User);
query.get(fromUserId, {
success: function(user) {
console.log("found user:");
console.log(user);
var fromUser = user;
var relation = fromUser.relation("friends");
relation.add(acceptingUser);
console.log("added accepting user to relation");
fromUser.save({
success: function() {
response.success("successfully saved user")
},
error: function() {
response.error("error saving user");
}
});
console.log("found a user");
},
error: function() {
console.log("error finding user");
}
});
});
An old question, but since it's been up-voted, maybe answering can help someone else :).
First off, there is an error in how you are saving fromUser.
fromUser.save({ success: ...
If you look at the api you can see that it should be of the form:
fromUser.save(null, { success: ...
But the larger problem that kept you from finding your bug is that errors are getting eaten 'cause you are using the old style method of dealing with async code instead of using promises.
Below, I have re-written to use promises. Note:
I always return promise generating calls (there are other options for catching errors in async code, but start with this.)
Put a .catch at the end. The .catch is effectively the same things as .then(null, response.error) but either way, it is imperative that there is final backstop to catch errors. In your code above, the error was in a success block, that was running async, so when there was an error, it failed with no one to hear it :).
Parse.Cloud.define("addFriendToFriendsRelation", (request, response) => {
const fromUserId = request.params.fromUserObjectId;
console.log("fromUserId:", fromUserId);
const acceptingUser = request.user;
console.log("acceptingUser:", acceptingUser)
new Parse.Query(Parse.User);
.get(fromUserId, { useMasterKey: true })
.then((fromUser) => {
console.log("found fromUser:", fromUser);
const relation = fromUser.relation("friends");
relation.add(acceptingUser);
console.log("added accepting user to relation");
return fromUser.save(null, { useMasterKey: true })
})
.then(response.success)
.catch(response.error);
});

Can't write user data to firebase

I'm new at this so bear with me. I'm trying to use the fire base simple login with the email and password. I have that working with this:
var authClient = new FirebaseAuthClient(fireRef, function(error, user) {
if (error) {
// an error occurred while attempting login
if(error.code === "INVALID_EMAIL"){
$('#log_email_error').hide();
$('#log_pass_error').hide();
$('#log_email_error').html("Invalid email specified.").fadeIn();
$('.login_button').removeClass('login_button_success').attr('value','Log in');
}
if (error.code === "INVALID_PASSWORD") {
$('#log_email_error').hide();
$('#log_pass_error').hide();
$('#log_pass_error').html("The specified password is incorrect..").fadeIn();
$('.login_button').removeClass('login_button_success').attr('value','Log in');
}
console.log(error);
} else if (user) {
// user authenticated with Firebase
hideLogin();
$('.userInfo_cont').show();
$('.userInfo').html('<div> '+ user.email + ' <span class="grey">| </span> </div>');
$('.logout').on('click',function(){
authClient.logout();
});
console.log('User ID: ' + user.id + ', Provider: ' + user.provider);
} else {
// user is logged out
$('.userInfo_cont').hide();
showLogin();
}
});
But when the user registers I want to store some additional info in a firebase/users area
which I can do with this in the registration:
$('#submit_reg').on('click',function(){
var firstName = $('#regFirstname').val();
var lastName = $('#regLastname').val();
var email = $('#regUsername').val();
var password = $('#regPassword').val();
authClient.createUser(email, password, function(error, user) {
if (!error) {
console.log('User Id: ' + user.id + ', Email: ' + user.email);
authClient.login('password', {
email: email,
password: password,
rememberMe: false
});
hideLogin();
userInfo = {
userId : user.id,
firstName : firstName,
lastName : lastName,
email : user.email
}
var url = USERS_LOCATION + "/" + user.id;
var userRef = new Firebase(url);
console.log(userInfo);
userRef.set(userInfo);
}else{
//display error
alert(error);
}
});
});
My Problem is when I implement the read write rules like the documentation has:
{
"rules": {
"users":{
"$userid": {
".read": "auth.id == $userid",
".write": "auth.id == $userid"
}
}
}
}
I get a permission denied when the user registers. So it registers the user just fine but won't write the additional data to the /users/id area.
Any help would be much appreciated.
Craig
In the snippet above, you're calling login(), and then immediately calling set() afterwards. This is problematic because the login() method is asynchronous, and you are almost always guaranteed to have called set() method prior to the return of the login attempt method, since login() is non-blocking yet makes a network call to the Firebase servers.
This means that even though you're calling login() with the correct email and password, you're trying to set the data before the authentication process has completed.
I would recommend moving your set() logic into a block that will only be executed when you are certain that the user has already authenticated, such as in the callback you passed when calling new FirebaseAuthClient() and detected a logged in user.

Categories

Resources