As per parse API documentation, "Security For Other Objects".
Create a private note that can only be accessed by the current user:
PFObject *privateNote = [PFObject objectWithClassName:#"Note"];
privateNote[#"content"] = #"This note is private!";
privateNote.ACL = [PFACL ACLWithUser:[PFUser currentUser]];
[privateNote saveInBackground];
Link: https://www.parse.com/docs/ios_guide#users-acls/iOS
This note will then only be accessible to the current user, although it will be accessible to any device where that user is signed in.
Question: How to retrieve all my private notes ? Unable to find out in documentation.
You have one add more column in your note class named "user" it creates user pointer in your table.
PFObject *privateNote = [PFObject objectWithClassName:#"Note"];
privateNote[#"content"] = #"This note is private!";
privateNote[#"user"] = [PFUser currentUser];
privateNote.ACL = [PFACL ACLWithUser:[PFUser currentUser]];
[privateNote saveInBackground];
And when you want to retrieve all notes which are related to that user then you can use following code
PFQuery *query = [PFQuery queryWithClassName:#"Note"];
[query whereKey:#"user" equalTo:[PFUser currentUser]];
NSArray *usersNote = [query findObjects];
NSLog(#"%#",usersNote);
in above Array u can get records.
Hope this will help to you.
Actually I've got another simple solution:
NO need to create extra column. You can simply use this:
PFObject *privateNote = [PFObject objectWithClassName:#"Note"];
privateNote[#"content"] = #"This note is private!";
privateNote.ACL = [PFACL ACLWithUser:[PFUser currentUser]];
[privateNote saveInBackground];
PFQuery *query = [PFQuery queryWithClassName:#"Note"];
NSArray *usersNote = [query findObjects];
NSLog(#"%#",usersNote);
It will automatically retrieve private note.
Related
If I have pointers to multiple _User objects in an array, can i query for a value of a User.
Ex.
I have a class Groups with an array members.
members = [user1, user2, user3].
Can I do something like:
PFQuery *query = [PFQuery queryWithClassName:#"Groups"];
[query whereKey:#"members.name" isEqual:#"James"];
This can be accomplished with a nested query. Create an "innerQuery" to find Users matching the criteria. Then constrain a Group query with whereKey:matchesQuery:.
PFQuery *innerQuery = [PFUser query];
// note that referring to the "name" field only makes sense if you've
// added a name field to User (you might mean username here)...
[innerQuery whereKey:#"name" isEqual:#"James"];
// now the main query is setup to match the innerQuery
PFQuery *query = [PFQuery queryWithClassName:#"Groups"];
[query whereKey:#"members" matchesQuery:innerQuery];
[query findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error) {
}];
I am designing a database. According to documentation, when number of relationships are greater than 100 and there is extra fields, I must design a Join Table. I designed this Join Table by having two pointer value.
This pointer value is pointing to _User. Later I need only rows for currUser.
This pointer value is the objectId of another table which is an entity. My question is, how can I write a query to return objects for this table in queryfortable.
Let's say:
Table _User
Table Entity
Table Join ---> objectId Pointer1(_User) Pointer2(Event)
This look like this:
This is what I have tried so far:
First I tried in viewDidLoad to get array of invitedUser from cloud and later in queryForTable:
PFQuery *query = [PFQuery queryWithClassName:#"Event"];
[query whereKey:#"objectId" containedIn:_inviteList];
but I need to access _inviteList.objectId which is not possible!
I tried to use innerQuerry or relation query. but as I just started learning parse I am not able to implement this.
PFUser *friendPointer = [PFUser currentUser];
PFQuery *query2 = [PFQuery queryWithClassName:#"Event"];
[query2 whereKey:friendPointer containedIn:_inviteList];
return query2;
This also did not work for me.
PFQuery *innerQuery = [PFQuery queryWithClassName:#"Invite"];
[innerQuery whereKey:#"invitedUser" equalTo:[PFUser currentUser]];
query = [PFQuery queryWithClassName:#"Event"];
[query whereKey:#"user" matchesQuery:innerQuery];
return query;
I appreciate if anyone can help me to write this query or re-design my table in order to have access to this query.
Pleaser try this code and give me review
PFUser *user = [PFUser currentUser];
PFQuery *query = [PFQuery queryWithClassName:#"Invite"];
[query whereKey:#"invitedUser" equalTo:user];
[query includeKey:#"invitedUser"];
[query includeKey:#"eventId"];
[query orderByDescending:#"updatedAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
if (error == nil)
{
for (PFObject *underobject in [objects reverseObjectEnumerator])
{
PFUser *user1 = underobject[#"invitedUser"];
NSLog(#"invitedUser is :%#",user1);
}
}
}];
I am trying to write a Parse query for my iOS social app that will show all users that are following the active user. Here is what I have so far:
PFQuery *followingUser = [PFQuery queryWithClassName:#"Activity"];
[followingUser whereKey:#"Activity" equalTo:#"follow"];
[followingUser whereKey:#"fromUser" equalTo:self.user];
[followingUser includeKey:#"User"];
[followingUser setCachePolicy:kPFCachePolicyCacheThenNetwork];
Currently this correctly gives me all the records of the active user following any other users, But this doesn't give me the PFUser details (user profile pic, display name, etc) for the corresponding records. Any ideas on how i can easily draw out the PFUser details in the one query?
Thanks in advance
Here is some sample code of a query that I used to get all the users being followed, all posts from the users being followed, and all posts from the current user. I hope this helps!
// List of all users being followed by current user
PFQuery *followingActivitiesQuery = [PFQuery queryWithClassName:kFTActivityClassKey];
[followingActivitiesQuery whereKey:kFTActivityTypeKey equalTo:kFTActivityTypeFollow];
[followingActivitiesQuery whereKey:kFTActivityFromUserKey equalTo:[PFUser currentUser]];
followingActivitiesQuery.cachePolicy = kPFCachePolicyNetworkOnly;
followingActivitiesQuery.limit = 100;
// Posts from users being followed
PFQuery *postsFromFollowedUsersQuery = [PFQuery queryWithClassName:self.parseClassName];
[postsFromFollowedUsersQuery whereKey:kFTPostUserKey matchesKey:kFTActivityToUserKey inQuery:followingActivitiesQuery];
[postsFromFollowedUsersQuery whereKey:kFTPostTypeKey containedIn:#[kFTPostTypeImage,kFTPostTypeVideo,kFTPostTypeGallery]];
// Posts from current user
PFQuery *postsFromCurrentUserQuery = [PFQuery queryWithClassName:self.parseClassName];
[postsFromCurrentUserQuery whereKey:kFTPostUserKey equalTo:[PFUser currentUser]];
[postsFromCurrentUserQuery whereKey:kFTPostTypeKey containedIn:#[kFTPostTypeImage,kFTPostTypeVideo,kFTPostTypeGallery]];
PFQuery *query = [PFQuery orQueryWithSubqueries:[NSArray arrayWithObjects: postsFromFollowedUsersQuery, postsFromCurrentUserQuery, nil]];
[query includeKey:kFTPostUserKey];
[query orderByDescending:#"createdAt"];
I'm building a private chat between 2 users. Currently I've got the "Chat" class open to everyone (read/write) and there is where all messages (objects) go.
I was thinking about adding objects with permission to read only between two users so only they can see what they chat.
I'm grabbing the messages using:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
PFQuery *fquery = [PFUser query]; // query to get the chat partener
[fquery whereKey:#"objectId" equalTo:[[NSUserDefaults standardUserDefaults] stringForKey:#"friendid"]];
PFUser *friend = (PFUser *)[fquery getFirstObject]; // got it!
PFQuery *query = [PFQuery queryWithClassName:#"Chat"]; // new query for grabbing messages
[query whereKey:PF_CHAT_ROOM equalTo:chatroom]; // #"Chat" = #"Chat"
if (message_last != nil) [query whereKey:PF_CHAT_CREATEDAT greaterThan:message_last.date];
[query includeKey:PF_CHAT_USER]; // current user
[query includeKey:[NSString stringWithFormat:#"%#", friend]]; // its friend/partener
[query orderByAscending:PF_CHAT_CREATEDAT]; // sort by date
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
// adding the messages to an array;
}];
For writing messages to parse:
PFObject *object = [PFObject objectWithClassName:#"Chat"]; // class name
object[PF_CHAT_ROOM] = chatroom;
object[PF_CHAT_USER] = [PFUser currentUser];
object[PF_CHAT_TEXT] = text;
PFQuery *query = [PFUser query];
[query whereKey:#"objectId" equalTo:[[NSUserDefaults standardUserDefaults] stringForKey:#"friendid"]];
PFUser *friend = (PFUser *)[query getFirstObject]; // query to get the chat partener
PFACL *roleACL = [PFACL ACL];
[roleACL setReadAccess:YES forUser:[PFUser currentUser]];
[roleACL setReadAccess:YES forUser:friend]; // setting read permission for those guys
object.ACL = roleACL;
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
....
}];
Is this the right way to go?
I've implemented a similar app taking the same approach which seemed to work. But I think you've over complicated for what it needs to be.
You need a Chat class which you seem to have. This may be something similar to:
Chat
Object ID, Message, Author, Date, Date Seen, ACL, etc....
(there's many good schemas out there just google it)
Then when you create a new chat message to a friend you simply just create a new PFObject setting the other user's ACL permission to like you've done correctly.
The user can read his messages by calling
PFQuery *query = [PFQuery queryWithClassName:#"Chat"];
The response of the query will only be the chats that the user has read permission to, not everyones. Therefore there's no need to specify any further query parameters unless you're looking for unread messages, etc..
I am using the backend service parse.com for a iOS app and I have a problem with querying it properly. I need help with the method whereKey:matchesKey:inQuery;
I have this code:
//NOT WORKING
PFQuery *query1 = [PFQuery queryWithClassName:#"Object"];
PFQuery *query2 = [PFQuery queryWithClassName:#"ObjectsRelations"];
[query2 whereKey:#"user" equalTo:[PFUser currentUser]];
[query1 whereKey:#"objectId" matchesKey:#"objectPointer" inQuery:query2];
[query1 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
// No objects
}];
It is not working the way I want. I have tried several ways for it to compare the key "objectPointer" in class "ObjectsRelations" (which is a pointer to an instance of class Object) to the actual Object in query 1. I do not get any objects back, because the comparison does not work as I want, since the key objectId is just a string and the key objectPointer is a pointer to a Object.
When I run this code, I get the intended result, but this requires me to do two api-requests to get the actual objectId as a string!
//WORKING
PFQuery *query = [PFQuery queryWithClassName:#"Object"];
PFQuery *query2 = [PFQuery queryWithClassName:#"ObjectRelations"];
[query2 whereKey:#"user" equalTo:[PFUser currentUser]];
[query2 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
PFObject *firstObject = [((PFObject*)[objects firstObject]) objectForKey:#"objectPointer"];
[query whereKey:#"objectId" equalTo:firstObject.objectId];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
//Getting the objects correctly from the class Object!
}];
}];
How to do this with a single api-request? How to compare a instance of a Class to a pointer of a class with a query?
Something like this is what i want to do: (Pseudo Code)
[query1 where:SELF matches:#"objectPointer" inQuery:query2];
Any suggestions?
I just searched this exact same problem and there are a number of questions on the Parse forum regarding it:
Trouble with nested query using object_id
Assistance with relational query
Compare string to pointer in query with does not match key in query
The first one explains a hack to include an extra field (in this case) in your ObjectRelations class. This key/field would be a string that would be the objectId of the pointer. It would be in addition to the key/field that holds the pointer.
If you look through the questions you can see that as of now there doesn't seem to be an answer directly from Parse regarding this.
Instead of adding an additional column with type String to contain the objectID it points to, I would suggest to add a column on each object with type Pointer to point to the object itself. This would dramatically reduce the amount of the columns you have to add. The only downside is this must be done on Cloud Code.
At this question's scenario, you'll have two queries like:
//Inner query
//Library containing pointer<Deck> & pointer<User>
PFQuery * subscriptions = [PFQuery queryWithClassName:#"subscription"];
[subscriptions whereKey:#"User" equalTo:[PFUser currentUser]];
//Outer query
//Pull down a list of deckStore objects not included in the subscriptions for current user
PFQuery * decks = [PFQuery queryWithClassName:#"deckStore"];
Then instead of:
[decks whereKey:#"objectId" doesNotMatchKey:#"deckString" inQuery:subscriptions];
You can do this:
[decks whereKey:#"this" doesNotMatchKey:#"deck" inQuery:subscriptions];
Here's a sample of what the Cloud Code should be added:
Parse.Cloud.afterSave("Deck", function(request) {
var deck = request.object;
// To make sure this is the first time of "afterSave" of this object.
if (deck.createdAt.getTime() == deck.updatedAt.getTime()) {
// "this" is the column which contains the pointer of the object itself.
if (deck.get("this") == null) {
deck.set("this", deck);
deck.save();
}
}
}
I have the same problem. This is my solution:
PFQuery *query1 = [PFQuery queryWithClassName:#"tableClass"];
[query1 whereKey:#"objectId" equalTo:[(PFObject *)[object objectForKey:#"pointerField"] objectId]];
PFObject *obj1 = [query1 getObjectWithId:[(PFObject *)[object objectForKey:#"pointerField"] objectId]];
NSString *pointerName = [obj1 objectForKey:#"name"];