Parse Cloud Code on Heroku User Query - heroku

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.

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
});

Is this achievable via Cloud Code on Parse?

I'm just starting with Parse (developing with Corona SDK). I've had no problems with basic usage such as getting and uploading data, authenticating users etc.
I have had some trouble getting my head around Cloud Code though.
Here's what I'm after:
My User class has an array column called exclude. For each user it contains some objectId's of objects stored in another class called questions. On request, I would like Parse to return all questions whose objectId's are NOT inside current user's exclude array.
I could do it without cloud code, by just downloading the whole questions class content and filtering it on device, but I thought it would be more efficient to do it server-side.
So is this achievable via Cloud Code? Do you know any examples I could look at to understand how to do it?
Edit: I've tried this function. It does not return anything. (exclude has been changed to doneQuestions)
Parse.Cloud.define("getQuestions", function(request, response) {
var query = new Parse.query("Questions");
query.notContainedIn("objectId", user["doneQuestions"]);
query.find({
success: function(objects) {
console.log();
},
error: function(error) {
console.log("An error occured :(");
}
});
});
You can use the notContainedIn constraint:
query.notContainedIn("objectId", user["exclude"]);

Parse.com not returning emailVerified value on User object

I've set up my app to enable email verification and the emails come through fine. Trouble is, when I make a call to retrieve a User object, either with Parse.User.current() or by querying by id, the response does not contain the emailVerified field. I can't therefore check if the user is email verified or not.
I've tried this both in client side code and in cloud code with the same result.
You can try this out in your own code with a very simple snippet in the console:
var user = Parse.User.logIn("your_username", "your_password", {
success: function(user) {
console.log(user)
}
});
That field seems to be protected, the only solution I can think of would be to query for where the value is true using some variant of where and check if you get a user back or not. If user is null, they haven't verified their email.

Updating existing Parse object in Cloud Code

I am using Parse for my backend and want to search for existing friend requests and update those instead of creating new ones (if there is already an existing one).
I thought I figured out how to do it but when I submit new friend requests they get created as new objects instead of updating the old one, even though I found an existing request.
Here is the code I am using:
Parse.Cloud.beforeSave("FriendRequest", function(request, response) {
//search for an existing friend request with the same "from" and "to"
var query = new Parse.Query("FriendRequest");
query.equalTo("from", request.object.get("from"))
.equalTo("to", request.object.get("to"));
query.find({
success: function(results) {
if(results.length > 0)
{
var result = results[0];
//the new request id is undefined as expected
console.log("request id: " + request.object.id);
//the result id is valid for an object in the db as expected
console.log("result id: " + results[0].id);
//set the id of the request to the id of the existing db object
request.object.id = results[0].id;
//the valid id is now in the request object id
console.log("request id: " + request.object.id);
//after response.success, the database shows a new entry
//with a different id
//instead of updating the existing entry
response.success();
}
}
});
});
There isn't a lot going on here. The query does come back successful with the correct entry in the database. I can confirm that I get the correct objectId for the existing item in the database. Any thoughts or ideas are appreciated!
You can't manually set the objectId of an object.
If you want beforeSave to NOT create a new object (which is what you're about to do when beforeSave is called), you need to manually update the existing object and then respond with a failure. If you respond with response.success(), the object will be saved normally.
In your code, you don't seem to make any changes to the existing object. All you really need to do is to return response.error (https://parse.com/docs/cloud_code_guide#functions-onsave)
Of course, you should also handle this in your code somehow. Either by alerting the user, or handling it silently.
However; why does your code attempt to save a new friend request if one already exist? Your app should know that one exists and disable the friend request button or whatever the UI offers.

Ember JS: How to load a second model based on data from a first

I have an Ember app that, rather than using Ember Data, uses our own custom AJAX data layer to talk to an API.
We're able to load two models at once using RSVP - one is a Project object via our API wrapper, the second is an object representing the logged in user. Both are passed into the controller and templates and work just fine.
But I have a need to load a second model, based on a value in the returned Project object.
Once I've loaded a model in my route like this...
App.ProjectUpdateRoute = Ember.Route.extend({
setupController: function(controller, model) {
controller.set('model', model);
},
model: function(params) {
return Ember.RSVP.hash({
// Load Project from API - /myapi/v1/Project/:ProjectID
Project : App.Project.create().findById(params.ProjectID),
// Load current user from local object
User : App.AuthUser,
});
},
});
...I have a Project object (or rather model.Project) with various properties including the ID of the User that owns the project.
Now I'd like to make a second API call to /myapi/v1/User/:UserID to get the User's details.
Everything I've tried - including adding further App.User.create().findById(UserID) calls into the route's setupController function and the controller - results in the correct API call, but it's asyncronous, so Ember carries on rendering the page and I can't show the result of the API call on the page.
So - how, and where in the Ember structure, do I load a second model based on data from the first? How can I get ember to wait for the resolved promise of this second AJAX call?
UPDATE
I've also tried using afterModel:function() which is almost what I need - it makes the second API call in the right place in the app flow, but I still need to add the result into my existing model array:
afterModel: function(model, tranistion, params) {
// Returns the promise but doesn't update 'model'
return Ember.RSVP.hash({
ProjectOwner : App.User.create().findById(model.Project.UserID)
});
}
Chain the promise, and Ember will take the final resultant (from the model hook)
model: function(params) {
return Ember.RSVP.hash({
// Load Project from API - /myapi/v1/Project/:ProjectID
Project : App.Project.create().findById(params.ProjectID),
// Load current user from local object
User : App.AuthUser,
}).then(function(results){
return App.User.create().findById(results.Project.UserID).then(function(user){
results.projectUser = user;
return results;
});
});
},

Resources