Im using parse with JS and i'm trying to do a reverse relationship...
I have the follow tables..
User
Offers
And the User table has a relationship column to relate a user to an offer and I have two types of relationships used_offers and saved_offers both of which tie the user to a offer.
I decided to put the relationship on the User table instead of the Offers table so that the ACL permission mean that only that user can read the relationship rather than anyone being able to read the relationship on a specific offer.
So... my question is... I am trying to list all the offers but I also want to join (if it exists) a relationship, ie so I know the in data returned it the offer is saved or used.
My current code looks like this...
//Get offer object and create query
var Offer = Parse.Object.extend("Offer");
var offerQuery = new Parse.Query(Offer);
var user = Parse.User.current(); //Get user object//Get user object
console.log(user); //Check user object exists (ie logged in)
offerQuery.whereEqualTo("saved_offers", user); //Get user object//Show relationships
offerQuery.include(["user"]); //Get user object//Return the user data also
offerQuery.find({
success: function(object) {
console.log(object);
},
error: function(error) {
console.log(error);
}
});
I get an error of... uncaught TypeError: undefined is not a function
Which im sure is related to the line...
offerQuery.whereEqualTo("saved_offers", user);
Super appreciate any help here, Parse is great but i cannot find specific documenation to use whereEqualTo (if this is the write command to call) in JS.
Many thanks!
It should be equalTo instead of whereEqualTo.
Related
I have an array property called courses on my User table in Parse. Any idea why I might getting Cannot modify user XTC9aiDZlL. code=206, message=Cannot modify user XTC9aiDZlL. when I do the following:
user.remove('courses', deletedCourse);
user.save()
where deleteCourse is the course PFObject to delete
Are you signed in as the user you're trying to modify? That can cause problems like this, as Parse usually just lets a user modify themself & the objects they've created.
If you're signed in as the same user you're trying to edit that's another story. This is a glitch that seems to be popping up in the Parse server recently. It's not the best solution but for now you'll need to modify the ACL when you create the user, like this:
let user = PFUser()
let acl = PFACL()
acl.getPublicWriteAccess = true
acl.getPublicReadAccess = true
user.acl = acl
hi i'm trying to implement getstream.io in my project.
i'm using https://github.com/GetStream/stream-js
as my server side script is in nodeJS.
i'm able to create a user in feed using
user1 = client.feed('user', 'dpz');
i'm creating activity for this user using using
activity ={
"actor":"user:1",
"message": "#flat_4_bfcaffca-c35f-11e5-8080-8001002e75f6",
"verb":"tweet",
"object":"tweet:4",
"foreign_id": "flat:4"
};
user1.addActivity(activity);
if i want to get all records of that user,
i use
user1.get()
.then(function(body) { console.log(JSON.stringify(body)); })
.catch(function(reason) { console.log(JSON.stringify(reason.error));});
i get result as :
{"duration":"19ms",
"next":"",
"results":[{
"actor":"user:1",
"foreign_id":"flat:4",
"id":"41231d40-ca5a-11e5-8080-800047dac62a",
"message":"#flat_4_bfcaffca-c35f-11e5-8080-8001002e75f6",
"object":"tweet:4",
"origin":null,
"target":null,
"time":"2016-02-03T09:41:09.335584",
"to":[],
"verb":"tweet"
}]
}
in your rest_ documentation
https://getstream.io/docs_rest/#feed_detail
you have specified
feed/(feed_slug)/(user_id)/(activity_id|foreign_id)/
to delete an activity for if the foreign key matches criteria.
in your nodejs code
user1.removeActivity({foreignId: 'flat:4'})
line works to remove the feed for that user where foreign key is flat:4
user1.get({foreignId: 'flat:4'})
does not work
can you please help if i want to get feeds with the foreignId as 'flat:4'
is there any way for such ?
please help as i'm stuck on this point only.
The feed/(feed_slug)/(user_id)/(activity_id|foreign_id)/ endpoint is only for DELETE requests. At this present is not possible to retrieve activities by its foreign_id. That field can only be used to perform cascaded deletion and/or to define the uniqueness of your data.
Looking at the code that you added, it seems like to use references to feeds as the value for foreign_ids, if that's the case then you are probably using this field in a weird/wrong way and you should create a new question on SO to ask help with the integration of your data.
I'm not able to use the node server debugger so I'm posting here to see if I can get a nudge in the right direction.
I am trying to allow multiple users to edit documents created by any of the users within their specific company. My code is below. Any help would be appreciated.
(Server)
ComponentsCollection.allow({
// Passing in the user object (has profile object {company: "1234"}
// Passing in document (has companyId field that is equal to "1234"
update: function(userObject, components) {
return ownsDocument(userObject, components);
}
});
(Server)
// check to ensure user editing document created/owned by the company
ownsDocument = function(userObject, doc) {
return userObject.profile.company === doc.companyId;
}
The error I'm getting is: Exception while invoking method '/components/update' TypeError: Cannot read property 'company' of undefined
I'm trying to be as secure as possible, though am doing some checks before presenting any data to the user, so I'm not sure if this additional check is necessary. Any advice on security for allowing multiple users to edit documents created by the company would be awesome. Thanks in advance. -Chris
Update (solution):
// check that the userId specified owns the documents
ownsDocument = function(userId, doc) {
// Gets the user form the userId being passed in
var userObject = Meteor.users.findOne(userId);
// Checking if the user is associated with the company that created the document being modified
// Returns true/false respectively
return doc.companyId === userObject.profile.companyId;
}
Looking at the docs, it looks like the first argument to the allow/deny functions is a user ID, not a user document. So you'll have to do Meteor.users.findOne(userId) to get to the document first.
Do keep in mind that users can write to their own profile subdocument, so if you don't disable that, users will be able to change their own company, allowing them to edit any post. You should move company outside of profile.
(If you can't use a proper debugger, old-fashioned console.log still works. Adding console.log(userObject) to ownsDocument probably would have revealed the solution.)
I have a _User class on parse for my application and i want to make it so that its ACL restricts writing from everywhere expect cloud code (W/ master key). The user has a "Verified" boolean column acknowledging weather they are a verified user or not. I do not want them to be able to log in, mess with the javascript, and write themselves in as "verified". I wrote this code but it wont work. Any suggestions?
Parse.Cloud.afterSave("_User", function(request, response) {
request.object.set("verifiedCritic",false);
var publicReadACL = new Parse.ACL();
publicReadACL.setPublicWriteAccess(false);
publicReadACL.setWriteAccess(request.object.id,false);
request.object.setACL(publicReadACL);
request.object.save();
response.success();
});
http://parse.com/docs/js/symbols/Parse.ACL.html#setReadAccess
check "setPublicREAD|WRITEAccess()" and use that in addition to the method you have for an individual user.ID.
When first created or when updated, IMO you want :
PubREAD TRUE
PubWrite FALSE
AND
Write ( thatUsserID, TRUE )
Then with the above and no other additional accretive assess in the array for the ACL , you should get the result that u want in cloud code after issuing "use_master_key" ...
After you create a user, can u use the databrowser to copy/paste the ACL column so that you can verify you have the correct collection of permissions? Then do your updating and the Cloudcode stuff.
I have a Player class. Players can have x number of Trophies. I have the Player objectId and need to get a list of all of their Trophies.
In the Parse.com data browser, the Player object has a column labeled:
trophies Relation<Trophy>
(view Relations)
This seems like it should be so simple but I'm having issues with it.
I have the ParseObject 'player' in memory:
var query = new Parse.Query("Trophy");
query.equalTo("trophies", player);
query.find({
/throws an error- find field has invalid type array.
I've also tried relational Queries:
var relation = new Parse.Relation(player, "trophies");
relation.query().find({
//also throws an error- something about a Substring being required.
This has to be a completely common task, but I can't figure out the proper way to do this.
Anyone know how to do this in Javscript CloudCode?
Many thanks!
EDIT--
I can do relational queries on the user fine:
var user = Parse.User.current();
var relation = user.relation("trophies");
relation.query().find({
I don't understand why this very same bit of code breaks if I'm using a non-user object.
I finally sorted this out, though there is a caveat that makes this work differently than the documentation would indicate.
//Assuming we have 'player', an object of Class 'Player'.
var r = player.relation("trophies");
r.query().find({
success: function(trophies){
response.success(trophies); //list of trophies pointed to by that player's "trophies" column.
},
error: function(error){
response.error(error);
}
})
The caveat: You must have a 'full' player object in memory for this to work. You can't save a player object, grab the object from the success callback and have this work. Some reason, the object that is returned in the success handler is appears to be an incomplete Parse.Object, and is missing some of the methods required to do this.
Another stumbling block about the Parse.com Javascript SDK- A query that finds nothing is still considered successful. So every time you query for something, you must check the length of the response for greater than 0, because the successful query could have returned nothing.
This is what worked for me:
var Comment = Parse.Object.extend("Comment");
var commentsQuery = new Parse.Query(Comment);
commentsQuery.equalTo("parent", video);//for the given 'video' instance, find its children (comments)
commentsQuery.descending("createdAt");
return commentsQuery.find();
Note: of course, video is an instance of the Video class. And returning find() means I'll have to handle the 'promise' in whatever function calls this one.
And here is another function coming from the other angle:
getRecentCommentsOfAllVideos: function(limit) {
var Comment = Parse.Object.extend("Comment");
var commentsQuery = new Parse.Query(Comment);
commentsQuery.descending("createdAt");
commentsQuery.limit(limit);
commentsQuery.include("parent");//this enables the details of the comment's associated video to be available in the result
return commentsQuery.find();
}
(Be sure to read https://parse.com/docs/js_guide and search for the line that says "Include the post data with each comment".)
I also looked at these materials; maybe they'll help you (though they weren't much help for me):
https://parse.com/questions/how-to-retrieve-parent-objects-with-their-children-in-one-call-javascript-api
http://blog.parse.com/2011/12/06/queries-for-relational-data/