I want to update a field within the User class without being logged in as a user. From reading online and other responses people say I should use the 'masterkey' to do so. Here is my cloud code where I have added in the master key. The code is executed but when I go to my data browser the totalScore and predictions values are still the same and not updated to the new values.
Parse.initialize("key", "key");
Parse.Cloud.define("userUpdate", function(request, response) {
Parse.Cloud.useMasterKey();
var publicReadACL = new Parse.ACL();
publicReadACL.setPublicWriteAccess(true);
request.object.setACL(publicReadACL);
var User = Parse.Object.extend("User");
var query = new Parse.Query(User);
query.equalTo("username", request.params.username);
query.find({
success: function(user) {
user.set("totalScore", request.params.totalS);
user.set("totalPredictions", request.params.totalG);
user.save()
},
error: function() {
response.error("f");
}
});
});
Any help would be massively appreciated.
Hopefully you've figured this out by now, but if you haven't...I would first say check to make sure that you're passing the "totalScore" and "totalPredictions" as numbers. If you pass them as strings and Parse is expecting a Number, it won't update. And generally, I believe it's best practice to query the user class as follows:
var query = new Parse.Query(Parse.User);
query.get(user.objectId, {
success: function(userAgain) {
userAgain.set("totalScore", totalScore);
userAgain.save(null, {
error: function(userAgain, error) {
// This will error, since the Parse.User is not authenticated
}
});
}
});
Then of course you'd still need to include the master key stuff etc...
Related
I recently created a cloud code function in order to fetch, edit, and save an array of strings named 'Friends'. It has a list of all of the friends that the user has. The function removes a specified user from that list. For some reason, whenever I tried to run it from the swift code, I got the error: JSON text did not start with array or object and option to allow fragments not set. Below is the function and the swift code I'm using. I'm not really sure why this is happening and I'd appreciate it if anybody could help me out.
Cloud code function:
Parse.Cloud.define("removeFriend", function(request, response) {
var userObjId = request.params.userObjId;
var currentUser = request.params.currentUser
var query = new Parse.Query(Parse.User);
query.equalTo("objectId", userObjId);
query.find({
success: function(results){
var friends = results["Friends"];
for(var i in friends){
if(friends[i]==currentUser){
array.splice(i,1);
i--;
break;
}
}
results["Friends"] = friends;
results.save(null, {
useMasterKey: true
});
response.success("User successfully removed & saved.");
},
error: function(){
response.error("The user was not successfully removed.");
}
});
});
Swift Code:
PFCloud.callFunction(inBackground: "removeFriend", withParameters: ["userObjId": friendObjId, "currentUser": currentUser!], block: { (success, error) in
if error != nil{
print(error!, "ASDASDASDASDJLASDLASDKNASD")
}else{
print("Successfully removed user")
}
})
I am trying to send a Push Notification through Parse Cloud Code when a certain object has been modified - "dirty"
I think I am almost there, but received an error because I believe am creating a new user instead of querying for one.
Parse.Cloud.beforeSave("Fact", function(request, response) {
var dirtyKeys = request.object.dirtyKeys();
for (var i = 0; i < dirtyKeys.length; ++i) {
var dirtyKey = dirtyKeys[i];
if (dirtyKey === "isValid") {
//send push
// Creates a pointer to _User with object id of userId
var targetUser = new Parse.User();
// targetUser.id = userId;
targetUser.id = request.object.userID;
var query = new Parse.Query(Parse.Installation);
query.equalTo('user', targetUser);
Parse.Push.send({
where: query,
data: {
alert: "Your Fact was approved :)"
}
});
return;
}
}
response.success();
});
I found this post related to my problem. My question now is how to integrate the user query in my beforeSave block. Ideally I would create another function for the user query and place that in my beforeSave block.
**5/14 Update
I took #toddg's advice and fixed the before save. Here is a clearer picture of what I am trying to do and the new error.
A couple points (as #Subash noted in the comments) before I get into the code:
Parse.Push.send is an async operation, so you'll want to ensure you call response.success() after your push send completes. I'm going to deal with this using Promises, as I think they are more flexible than callbacks. If you're not familiar, read about them here
The return in your if statement will likely prevent the response.success() from being called.
Here's my recommended way of doing it:
Parse.Cloud.beforeSave("Fact", function(request, response) {
// Keep track of whether we need to send the push notification
var shouldPushBeSent = false;
var dirtyKeys = request.object.dirtyKeys();
for (var i = 0; i < dirtyKeys.length; ++i) {
var dirtyKey = dirtyKeys[i];
if (dirtyKey === "isValid") {
shouldPushBeSent = true;
}
}
if (shouldPushBeSent) {
//send push
// Creates a pointer to _User with object id of userId
var targetUser = new Parse.User();
// targetUser.id = userId;
targetUser.id = request.object.userId;
var query = new Parse.Query(Parse.Installation);
// We want to pass the User object to the query rather than the UserId
query.equalTo('user', targetUser);
Parse.Push.send({
where: query, // Set our Installation query
data: {
alert: "Your fact was approved"
}
}).then(function(){
// Now we know the push notification was successfully sent
response.success();
}, function(error){
// There was an error sending the push notification
response.error("We had an error sending push: " + error);
});
} else {
// We don't need to send the push notification.
response.success();
}
});
By the way, I'm assuming that you have a column on your Installation class that tracks which user is associated with each Installation.
I am currently using LDAP JS for Authentication in Angular JS app and everything works perfectly fine.
I am now building a new view and the requirement I have is this:
I have text box in which admin will write may be a few letters of a user id present in LDAP.
I want to show app matching ID present in LDAP on a typeahead/suggestions. I know how typeahead works so that's not an issue. The issue is how can I pass a rejex or pattern matching kind of a thing for uid in search() method.
My sample code is here:
function GetAllLDAPUser(dnFilter, res) {
client.search('uid=**WHAT-PATTERN-CAN-I-PASS-HERE**' + dnFilter, opts, function(err, result) {
result.on('searchEntry', function(entry) {
// I usually read entry.object or entry.raw here , that works
});
result.on('end', function(result) {
.......
});
}
}
}
So the question is what should I pass in place of
WHAT-PATTERN-CAN-I-PASS-HERE
Results :
Suppose I type an. The typeahead will show all user id starting with an like ana, anamon, analisa etc.
I have written the final solution and closed the issue on the project's repository
For pattern matching, we need to play with the 'filter' field in option object which we pass to the search method. So I ended up doing something like below:
var dnFilter = 'ou=People,o=Intra,dc=YOURCOMPANY,dc=com'; //depends on your LDAP settings.
var query;
var matchedUsers = [];
query.LDAPName = "dummy"; //some name which resides in LDAP
//You can even have one simple variable rather than having this query object.
opts = {
scope: 'sub',
filter: (shcDisplayName = '+ query.LDAPName + ')
'
};
//Do not use 'shcDisplayName' , this will be any variable stored in your LDAP object. You need get
//the structure of LDAP end point you are working on. For me, I had one variable 'shcDisplayName'
//on which I wanted to play so I am using this variable in my filter.
client.search(dnFilter, opts, function(err, result) {
result.on('searchEntry', function(entry) {
matchedUsers.push({
'Name': entry.object.shcDisplayName,
'Id': entry.object.uid
});
}
result.on('end', function(result) {
if (matchedUsers.length) { //if any match was found.
//send the json result back
res.json(matchedUsers);
//if you want to send json back, do not use res.send() otherwise you will end up getting
//circular reference error.
}
}
result.on('error', function(ex) {
//Handle errors here if any
});
});
}
}
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');
});
});
Presently I am using Cloud Code along with the masterkey to modify attributes of other users based on actions of current user. I have an attribute requests_from, and I have managed to add items to this array based on the following code:
Parse.Cloud.define('requestUser', function(request, response) {
var userId = request.params.userId,
requestsFrom = request.params.requestsFrom;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
user.add('requests_from', requestsFrom); //Changed from set to add
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
I have used the above code to add currentUser.objectId to a target user's requests_from column.
However, my issue is now deleting items from requests_from. Once the current user has done an action, I would like to remove currentUser.objectId from requests_from. However, using user.remove or user.delete isn't working. I was wondering if there is another way to accomplish this via Cloud Code?
Thanks
I hope this answer helps you if you haven't already solved it ! Basically, after researching and failing to find anything, it appears that the solution to this is to do the following:
Parse.Cloud.define('removeRequest', function(request,response){
var userId = request.params.userId;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
var currentUser = request.user;
var relation = user.relation("request");
relation.remove(currentUser);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});