I have written a cloud code to change a Boolean value in table. The code is getting executed and the values are getting updated as well. But the issue is that I get the following error printed in my console. I am worried if this might cause a problem if the number of rows increase. Following is the error which is being printed on the console
I2015-09-15T06:15:48.317Z]v11: Ran job hello with:
Input: {}
Failed with: Error: Job status message must be a string
at updateJobMessageAndReturn (<anonymous>:1157:7)
at Object.success (<anonymous>:1211:9)
at e.obj.save.success (main.js:25:30)
at e.<anonymous> (Parse.js:12:27827)
at e.s (Parse.js:12:26759)
at e.n.value (Parse.js:12:26178)
at e.<anonymous> (Parse.js:12:26831)
at e.s (Parse.js:12:26759)
at e.n.value (Parse.js:12:26178)
at e.s (Parse.js:12:26887)
Following is the cloud code:
Parse.Cloud.job("hello", function(request, response) {
Parse.Cloud.useMasterKey();
var presentDate = new Date();
// presentDate.setDate(presentDate.getDate()-1);
presentDate.setHours(0,0,0,0);
var usersValid = new Parse.Query(Parse.User);
usersValid.equalTo("emailVerified", true);
//usersValid.greaterThan("updatedAt", presentDate);
var users = new Parse.Query("Properties");
users.matchesQuery("user",usersValid);
users.equalTo("verified", false);
users.limit(1000);
users.find({
success: function(results) {
console.log("Total new properties "+ results.length);
for (var i = 0; i < results.length; i++) {
var obj = results[i];
obj.set("verified", true);
obj.save(null,{
success: function (object) {
console.log("Success - "+i);
response.success(object);
},
error: function (object, error) {
console.log("Failed - "+i);
response.error(error);
}
});
}
},
error: function(error) {
console.log("failed");
}
});
When you call
response.success(object);
you're passing the full object that was just saved - but you shouldn't be. You can just call success with a simple status string, like 'OK', or with some element from the saved object, like its object id.
The more serious issue is that you're requesting 1000 items in the query and then updating and saving each individually - and in the save completion handler you're calling success or error. So, as soon as the first of those 1000 objects is saved you're telling the job it's complete and it can stop processing the rest.
You should change your job to use promises instead of old style callbacks and you should put all of the save promises into an array and wait for them to complete after your loop before you call success or error.
I'm trying to send an email via parse.com via mandrill. The examples are very easy to follow, but I'm getting a strange error.
here is my code:
Parse.Cloud.afterSave("ip", function(request) {
var IPLogger_config = require('cloud/mandrillapp_config.js');
var Mandrill = require('mandrill');
Mandrill.initialize(IPLogger_config.mandrillAppKey);
console.log('within afterSave for ip');
console.log(request.object.id);
var ip = Parse.Object.extend("ip");
var query = new Parse.Query(ip);
query.descending("createdAt");
query.limit(2); // limit to at most 2 results
query.find({
success: function(results){
console.log('success query');
console.log('got ' + results.length + ' results');
var newestIp = results[0];
var olderIp = results[1];
if (newestIp.get('ip') == olderIp.get('ip') ) {
// the newest ip and the older one are equal, do nothing.
console.log('No ip change');
} else
{
console.log('ip change!');
console.log(Mandrill.initialize);
console.log(Mandrill.sendEmail);
Mandrill.sendEmail({
message: {
text: "The IP of your server has changed! The new ip is: " + newestIp.get('ip') ,
subject: "The IP of your server has changed!",
from_email: "parse#cloudcode.com",
from_name: "IPLogger",
to: [
{
email: IPLogger_config.your_email,
name: IPLogger_config.your_name
}
]
},
async: true
},{
success: function(httpResponse) {
console.log(httpResponse);
response.success("Email sent!");
},
error: function(httpResponse) {
console.error(httpResponse);
response.error("Uh oh, something went wrong");
}
});
}
},
error: function (error){
console.log('no success for query');
console.error("Got an error " + error.code + " : " + error.message);
}
});
});
my mandrillapp_config.js looks like this:
var IPLogger_config = {};
IPLogger_config.mandrillAppKey = "xxx";
IPLogger_config.your_email = 'myemail#bla.com';
IPLogger_config.your_name = 'myName';
The mandrillAppKey is correctly set. I double checked that. Sending email from mandrill website also works. I just created a new account and did no other settings on the mandrill site.
I'm getting this error: "code":-1,"name":"ValidationError","message":"You must specify a key value". In https://www.parse.com/questions/sometimes-getting-mandrill-you-must-specify-a-key-value-error-when-sending-email is written that the header might be wrong, but as you can see on my log, the "Content-Type":"application/json; charset=utf-8" is set correctly.
I2014-06-09T22:34:20.601Z] {
"uuid":"fbb215c4-1d2a-e2da-23fc-a838bd6bf217",
"status":500,
"headers":{
"Access-Control-Allow-Credentials":"false",
"Access-Control-Allow-Headers":"Content-Type",
"Access-Control-Allow-Methods":"POST, GET, OPTIONS",
"Access-Control-Allow-Origin":"*",
"Connection":"close",
"Content-Encoding":"gzip",
"Content-Type":"application/json; charset=utf-8",
"Date":"Mon, 09 Jun 2014 22:34:20 GMT",
"Server":"nginx/1.6.0",
"Vary":"Accept-Encoding",
"X-Powered-By":"PHP/5.3.10-1ubuntu3.11"
},
"text":"{\"status\":\"error\",\"code\":-1,\"name\":\"ValidationError\",\"message\":\"You must specify a key value\"}",
"data":{"status":"error","code":-1,"name":"ValidationError","message":"You must specify a key value"},
"buffer":{"0":123,"1":34,"2":115,"3":116,"4":97,"5":116,"6":117,"7":115,"8":34,"9":58,"10":34,"11":101,"12":114,"13":114,"14":111,"15":114,"16":34,"17":44,"18":34,"19":99,"20":111,"21":100,"22":101,"23":34,"24":58,"25":45,"26":49,"27":44,"28":34,"29":110,"30":97,"31":109,"32":101,"33":34,"34":58,"35":34,"36":86,"37":97,"38":108,"39":105,"40":100,"41":97,"42":116,"43":105,"44":111,"45":110,"46":69,"47":114,"48":114,"49":111,"50":114,"51":34,"52":44,"53":34,"54":109,"55":101,"56":115,"57":115,"58":97,"59":103,"60":101,"61":34,"62":58,"63":34,"64":89,"65":111,"66":117,"67":32,"68":109,"69":117,"70":115,"71":116,"72":32,"73":115,"74":112,"75":101,"76":99,"77":105,"78":102,"79":121,"80":32,"81":97,"82":32,"83":107,"84":101,"85":121,"86":32,"87":118,"88":97,"89":108,"90":117,"91":101,"92":34,"93":125,"length":94,
"parent":{"0":123,"1":34,"2":115,"3":116,"4":97,"5":116,"6":117,"7":115,"8":34,"9":58,"10":34,"11":101,"12":114,"13":114,"14":111,"15":114,"16":34,"17":44,"18":34,"19":99,"20":111,"21":100,"22":101,"23":34,"24":58,"25":45,"26":49,"27":44,"28":34,"29":110,"30":97,"31":109,"32":101,"33":34,"34":58,"35":34,"36":86,"37":97,"38":108,"39":105,"40":100,"41":97,"42":116,"43":105,"44":111,"45":110,"46":69,"47":114,"48":114,"49":111,"50":114,"51":34,"52":44,"53":34,"54":109,"55":101,"56":115,"57":115,"58":97,"59":103,"60":101,"61":34,"62":58,"63":34,"64":89,"65":111,"66":117,"67":32,"68":109,"69":117,"70":115,"71":116,"72":32,"73":115,"74":112,"75":101,"76":99,"77":105,"78":102,"79":121,"80":32,"81":97,"82":32,"83":107,"84":101,"85":121,"86":32,"87":118,"88":97,"89":108,"90":117,"91":101,"92":34,"93":125,"length":94},"offset":0},"cookies":{}}
Where can be the problem? any ideas how to get it running?
thank you very much!
I finally found the problem. There was en error in the config script.
it need to look like this:
var IPLogger_config = {};
IPLogger_config.mandrillAppKey = "xxx";
IPLogger_config.your_email = 'myemail#bla.com';
IPLogger_config.your_name = 'myName';
exports.IPLogger_config = IPLogger_config;
in the main.jsfile, the resources of the config file need to be called like this:
var config = require('cloud/mandrillapp_config.js');
Mandrill.initialize(config.IPLogger_config.mandrillAppKey);
and now it works fine.
I send a request to parse that includes a Comment object that has a pointer to a User named "from".
In afterSave I need to read this and I'm having all kinds of problems. beforeSave works just fine, but I want to execute this code in afterSave;
Parse.Cloud.afterSave("Comment", function(request) {
var userQuery = new Parse.Query("User");
userQuery.get(request.object.get("from").id, {
success: function(user) {
},
error : function(error) {
console.error("errrrrrrrr" + error);
}
});
});
Here is the log I'm seeing on parse
errrrrrrrrr [object Object]
EDIT:
I also tried
var userQuery = new Parse.Query("_User");
Seems like I had to call useMasterKey, since I was fetching a user data.
I'm not entirely sure about this though so I'll keep this question open.
Parse.Cloud.useMasterKey();
Have you tried this?
var userQuery = new Parse.Query(Parse.User);
Try to fetch the pointer directly:
var fromUserPointer = request.object.get("from");
fromUserPointer.fetch().then(function(fetchedFromUser){
},function(error){
});
Slightly different approach.
This assumes that you have the comment object available right there, or at least its id.
Instead of querying the User collection, how about this:
var commentQuery = new Parse.Query("Comment");
commentQuery.include("from");
commentQuery.get(<commentId>, {
success: function (comment)
{
var user = comment.get("from"); // Here you have the user object linked to the comment :)
},
error: function (error)
{
console.log("ERROR: ");
console.log(error);
}
});