User not found on cloud code call? Why? - parse-platform

I want to check if the cloud code request came from an actual user and then return data for that user only.
Here is my code. It passes the !currentUser test most of the time, but fails frequently even though I know there is a user making the request. Any ideas?
CODE:
Parse.Cloud.define("getData", function(request, response) {
var currentUser = request.user;
if(!currentUser) {
response.error("Failure: No user found on getData function");
return;
}
}
ERROR: Failed with: Failure: No user found on getData function
Could this be due to ACLS?

Your logic seems entirely valid, I would suggest just before your response.error() call that you do a console.log(request); so you can look at the log and see more detail.
It could be that your calling code is making a request before the login has completed in the background (race condition), or that requests are being made after a user logs out.

Related

Call cloud code without logged in user Parse Server JS SDK

Is it possible to call a cloud function that returns objects without having a current user? The iOS and Android SDKs support anonymous users but I'm asking specifically for JavaScript.
I'd like to allow it so that anyone who visits my web app can read objects without having to sign in. I'm using Back4App.
Yes. You can call a cloud code function no matter the user is logged in or not. Inside the cloud function you can check the user property of the request object to check if the user is either logged in or not. In the case that your user is not logged in and you want to query a class which requires user permission, you can use the useMasterKey option.
Parse.Cloud.define('myFunction', async req => {
const { user, isMaster } = req;
if (isMater) {
// the cloud code function was called using master key
} else if (user) {
// the cloud code function was called by an authenticated user
} else {
// the cloud code function was called without passing master key nor session token - not authenticated user
}
const obj = new Parse.Object('MyClass');
await obj.save(null, { useMasterKey: true }); // No matter if the user is authenticated or not, it bypasses all required permissions - you need to know what you are doing since anyone can fire this function
const query = new Parse.Query('MyClass');
return query.find({ useMasterKey: true }) // No matter if the user is authenticated or not, it bypasses all required permissions - you need to know what you are doing since anyone can fire this function
});

Parse Cloud Code on Heroku User Query

I am trying to access properties located on the User object for the current user in a cloud code function. The current user is passed to the cloud code function and available at request.user. The Cloud Code is deployed to Heroku using parse-cloud-express.
When the request first arrives, it does not contain the user data other than the id.
So I tried performing a fetch to get the latest data:
Parse.Cloud.define("functionName", function (request, response) {
request.user.fetch().then(function (user) {
console.log(util.inspect(user));
});
});
But it outputs the same data and does not seem to include the User object's properties.
2015-12-15T01:19:08.830880+00:00 app[web.1]: { _objCount: 1, className: '_User', id: 'dKqZMSRgDc' }
I also tried performing a query on the user id, but receive the same result.
var userQuery = new Parse.Query(Parse.User);
userQuery.get(request.user.id).then(function (user) {
console.log(util.inspect(user));
});
How do I get the properties of the User object?
The problem was not with getting data for the User object, but the way I was logging it. It seems that the data is not available from the object itself, so the output from util.inspect was correct, but does not include any properties. (I'm guessing the internals of the Parse framework manages this in another way.)
I replaced with console.log(user.toJSON()) and can now see the expected data for the user.

Reload page with new context in express

I have a page that lists events, in which admins are can delete individual items with an AJAX call. I want to reload the page when an event is deleted, but I am having trouble implementing it with my current understanding of express' usual req, res, and next.
Here is my current implementation (simplified):
Simple jQuery code:
$(".delete").click(function(e){
$.post("/events/delete",{del:$(this).val()})
})
in my routes file:
function eventCtrl(req,res){
Event.find({}).exec(function(err,events){
...
var context = {
events:events,
...
}
res.render('events',context);
});
}
function deleteCtrl(req,res,next){
Event.findById(req.param("del")).exec(function(err,event){
// delete my event from google calendar
...
event.remove(function(err){
...
return next();
});
});
}
app.get('/events',eventCtrl);
app.post('/events/delete',deleteCtrl,eventCtrl);
When I make a post request with AJAX all the req handlers are called, the events are deleted successfully, but nothing reloads. Am I misunderstanding what res.render() does?
I have also tried using a success handler in my jQuery code when I make the post request, with a res.redirect() from deleteCtrl, but my context is undefined in that case.
on the client side, you are using
$(".delete").click(function(e){
$.post("/events/delete",{del:$(this).val()})
})
this code does not instruct the browser to do anything when the response from the post is received. So nothing visible happens in the browser.
You problem is not located server side ; the server answers with the context object. You are simply not doing anything with this answer.
Try simply adding a successHandler.
Generally speaking this would not be a best practice. What you want to do is reconcile the data. If the delete is successful, then just splice the object out of the array it exists in client-side. One alternative would be to actually send back a refreshed data set:
res.json( /* get the refreshed data set */ );
Then client-side, in the callback, you'd actually just set the data source(s) back up based on the result:
... myCallback(res) {
// refresh the data source(s) from the result
}

Waiting for mixpanel JS lib to be ready so I can get users distinct_id

We want to use MixPanel to capture events on our site and I'm trying to get hold of the users distinct id, so I'm using the following code snippet:
$(document).ready(function($){
console.log("We have distinct id");
console.log(mixpanel.get_distinct_id());
});
This causes an error saying 'undefined is not a function' when attempting to get the distinct id.
I've checked in the debugger and can confirm that the mixpanel object does not have a get_distinct_id method, However if I wait until the page has loaded and then evaluate mixpanel.get_distinct_id() in the console, I get the distinct id without problem.
I can only guess that the mixpanel object hasn't completed initialisation yet. Is there a callback or an event that I can use to know once the mixpanel object will be able to tell me the users distinct_id?
From a Mixpanel article:
"[...] pass a config object to the mixpanel.init() method with a loaded parameter and a callback function that will execute immediately after our library has finished loading. Inside the callback function, you can use the get_property() and get_distinct_id() methods and ensure that they'll only execute after the library has finished loading."
mixpanel.init('Project Token', {'loaded':function() {
var distinct_id = mixpanel.get_distinct_id()}
});
Source: How to prevent get_distinct_id & get_property from returning undefined
I found a code snippet here: https://gist.github.com/calvinfo/5117821, credit to https://gist.github.com/calvinfo which looks like this:
$(document).ready(function() {
if ($("#mixpanel_distinct_id").length > 0) {
var interval = setInterval(function () {
if (window.mixpanel.get_distinct_id) {
$("#mixpanel_distinct_id").val(window.mixpanel.get_distinct_id());
clearInterval(interval);
}
}, 300);
}
});
Basically this allows you to check every 300 milliseconds whether the mixpanel object has completed initializing and the get_distinct_id function is available.
You make get district_id from cookie:
cookie = document.cookie.split(";")[0];
distinct_id = cookie.substr(74,53);
but correctly use regexp
Good luck!

How to handle application errors for json api calls using CakePHP?

I am using CakePHP 2.4.
I want my frontend make api calls to my CakePHP backend using ajax.
Suppose this is to change passwords.
Change password action can throw the following application errors:
old password wrong
new password and confirm new passwords do not match
In my frontend, I have a success callback handler and a error callback handler.
The error callback handler handles all the non 200 request calls such as when I throw NotFoundException or UnAuthorizedAccessException in my action.
The success callback handler handles all the 200 request calls including of course, the above 2 scenarios.
My questions are:
Should I continue to do it this way? Meaning to say, inside all success callback handler, I need to watch out for application success and application error scenarios.
Should I send application errors back with actual HTTP error codes?
if I should do 2, how do I implement this in CakePHP?
Thank you.
Don't use http error codes for system errors like:
old password wrong
new password and confirm new passwords do not match
etc etc...
Now using success handler you can show messages and code flow as:
Create Ajax post or get to submit the form, I am showing you post example
var passwordValue = $('#password').val();
$.post( "/updatePassword", { passwordText: passwordValue })
.done(function(response) {
if(response.status === 'Success'){
// Success msg
// whatever
}else{
// Error msg
// whatever
}
});
json response would like:
{
"status": "Failed/Success",
"message": "old password wrong."
}
Create one function in controller
public function updatePassword() {
$myModel = $this->MyModel->find('first' // YOUR CODE LOGIC);
if($this->request->is('ajax') {
$this->layout=null;
// What else?
echo json_encode($myModel);
exit;
// What else?
}
}
Do something like this, hope it will solve your query!

Resources