When adding an email address to a list I'd like to check in a beforeSave function in my cloud code if the address belong to an existing user. If it doesn't I'd like to stop the save call and return an error response to my mobile app.
When I run the below code I have no problem while entering a valid email address. As soon as I enter an invalid address however the beforeSave function goes into a tizzy and times out after some time, returning a load of rubbish to the the client.
Parse.Cloud.beforeSave("EventUsers", function(request, response) {
var email = request.object.get("email");
console.log("starting beforeSave for user: " + email);
Parse.Cloud.useMasterKey();
var userQuery = new Parse.Query(Parse.User);
userQuery.equalTo("email", email);
userQuery.first().then(function(user) {
console.log("user: " + user.get("email"));
if (user) {
console.log("User exists");
response.success();
}
console.error("No user with that email");
response.error("199");
}, function(error) {
console.error(error);
response.error("198");
});
});
When I run this with an invalid email address I only get the very first console.log calls reported to my console - none of the others are showing.
I'm running my parse server on Heroku.
Are you running this on parse.com or on your own mongo db backend?
In any event, your problem is that email is likely not indexed so it is doing a full table scan. If it is your own backend, you can put an index on email in the collection.
If you're running your own db, not sure if anyone has done it yet (I haven't yet, but should), but you can probably also just put a unique constraint on email and then you can simply catch the rejected promise on user.save() and not worry about the beforeSave hook at all.
Related
I am using googleapis in NodeJS to create & fetch the calendar events. I am using the following method to get the list of events.
const getEvents = async (dateTimeStart, dateTimeEnd,timeZone) => {
console.log("Date Start : " + dateTimeStart + " date end :" + dateTimeEnd + " time zone " + timeZone);
try {
let response = await calendar.events.list({
auth: auth,
calendarId: CALENDER_ID,
timeMin: (new Date(dateTimeStart)).toISOString(),
timeMax: (new Date(dateTimeEnd)).toISOString(),
timeZone: timeZone,
singleEvents: true,
maxResults: 9999,
orderBy: 'startTime
});
let items = response['data']['items'];
console.log(items);
return items;
} catch (error) {
console.log(`Error at getEvents --> ${error}`);
return 0;
}
};
The above method returns only events that are created programmatically via googleapis. If I create the events directly on the calendar from the browser this does not return those events.
Any idea how to fetch all events even if they are created from browser.
Based on what you were explaining about the behavior of the events being created by the service account instead of the actual users I think the problem is that the events created through API are being created under the Calendar ID of the service account, and the ones created by the users through API may have a different Calendar ID, therefore when you try to get the list of events, since you are probably using the Calendar ID from the service account you get only those events created using the API and not the ones created by the users through the web UI.
In this case it may be necessary to make sure that every event is being created under the exact same calendar ID through the web UI and the API so that all the events no matter if they were created through the API or web UI get listed as expected.
Let me know if this is useful, otherwise I can edit the response to add more clarification depending on your specific situation.
I don't know why I'm not getting notification events from sails models from model.publish().
In pre-1.x sailsjs, similar client-side code had worked and I would get every event when records are created, updated or deleted. So, I must be misunderstanding something.
How do I subscribe to all events for any records from CRUD operations?
On the server side, I have Job.js and JobController.js.
In Job.js model, this test just creates a new record every 10 secs:
test: async function(dataset) {
let count = 0;
setInterval(async function() {
count++;
let newjob = {
dataset: dataset,
state: 'delayed',
name: "job name "+count
};
let job = await Job.create(newjob).fetch()
sails.log.info('created test job: ',JSON.stringify(job));
Job.publish([job.id],job);
},10000);
}
In JobController.js, called by the client and starts the test rolling:
submittest: async function(req,res) {
let dataset = await Dataset.Get({});
await Job.test(dataset[0].id);
return res.ok({status:'ok'});
}
In the client test.html, io.socket.get operations are successful, but I never see an event:
...
<script>
io.socket.get('/job', function(body, JWR) {
console.log('and with status code: ', JWR.statusCode);
setTimeout(function() {
io.socket.get('/job/submittest', function (body,JWR) {
io.socket.on('job', function(msg) {
console.log("job event",msg); // not getting here. why?
});
});
},2000)
});
</script>
This all runs fine but the problem is, no events are seen from the client side. Why? Am I not subscribed to events with the initial io.socket.get('/job')?
Essentially, what is happening here, is you are shouting into an empty box about a new record in your model, but no one is listening to you in that empty box.
In other words, you need to subscribe the socket connection to the model updates.
See: https://sailsjs.com/documentation/reference/web-sockets/resourceful-pub-sub/subscribe
Also, checkout the answer to this question for a quick how to.
I am writing a google web app which uses the Admin Directory a lot. However I was wondering how the error handling should be done since I do not get a proper error object back when a request to the api fails.
Example: I want to check if a custom schema exists and if not I want to do something else:
try{
var resp = AdminDirectory.Schemas.get("129898rgv", "someCustomSchema");
}catch(err){
// if schema does not exist do this
schemaNotExistFunction();
Logger.log(err);
}
Unfortunately I do not even get the http status code back from the err. Is there another way to handle errors in Google Apps Script?
Instead of
Logger.log(error)
use
Logger.log('%s, %s',error.message, error.stack);
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error for a complete list of Error instance properties
The above because Logger.log parses the parameter as string. When you pass an error object error.name is logged, by the other hand by using
Example
Running the following code in an standalone project using the new runtime (V8) will log a couple of messages.
function myFunction() {
try{
SpreadsheetApp.getUi();
} catch (error) {
Logger.log(error);
Logger.log('%s, %s', error.message, error.stack);
}
}
Another alternative is to use console.log instead of Logger.log
function myFunction() {
try{
SpreadsheetApp.getUi();
} catch (error) {
console.log(error);
console.log('%s, %s', error.message, error.stack);
}
}
We made a mistake in our client code where some users attempt to save a false boolean flag (by mistake) and others save a string to the same key in our Parse database.
I'm getting error code from Parse from everyone setting the false boolean as follows:
{"code":111,"error":"invalid type for key premiumType, expected string, but got boolean"}
Until we can release the next version of our client code, I want to intercept and correct this error IN CLOUD CODE. I'm trying this:
Parse.Cloud.beforeSave('GameScore', function(request, response) {
console.log("Entered function");
var premiumType = request.object.get("premiumType");
if (premiumType) {
request.object.set("premiumType", null);
response.success();
} else {
response.success();
}
});
But, the beforeSave function does not get entered unless the key type is correct, so I cannot modify the object here.
Are there any other locations where I can intercept this and modify the code in the cloud?
I am getting the error response as "user objects cannot allow writes from other users" when trying to signUp or update a ParseUser in cloud code.
As specified by the Parse team I am using Parse.Cloud.useMasterKey() so that I can bypass the restrictions.
Where possibly am I going wrong? I am confused as this code was previously working.
Thanks in advance.
If it is possible, can you provide some codes related with your problem? For example below code is updating the Parse User name column successfully (tested on Parse cloud);
Parse.Cloud.define("test", function(request, response) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.equalTo("objectId", request.params.objectId);
query.first({
success: function(object) {
object.set("name", request.params.name);
object.save();
response.success("Success Message");
},
error: function(error) {
response.error("Error Message");
}
});
});
However, if one of the ParseUser tries to update another then it is highly possible the problem is related with the ACL. If you provide codes, it is really helpful. Hope this helps,
Regards.