PFQuery constraints - exclude subquery - ios

I have a table called "match". this table has several columns of type string.
I'm trying to create a query that queries for the string value "undefined" in column "player2". That works without problem. When I query for just that I get the results.
But I want to add a constraint so that it excludes the match objects where the current user's facebook id matches that of column "player1". I've stored the id in the PFUser object so i can easily retrieve it.
I'm creating a random player matching system where the query checks for an open spot in the match table's "player2" column. if it's "undefined" I know that there is an open slot in the match and the player can join it.
However it needs to exclude the matches the current player previously started himself. Otherwise it would join a match the current player started himself.
//check for objects that match the string "undefined"
PFQuery *query1 = [PFQuery queryWithClassName:#"match"];
[query1 whereKey:#"player2" containsString:#"UNDEFINED"];
//AND constraint to exclude the match of query1 if the current user id matches
PFQuery *query2 = [PFQuery queryWithClassName:#"match"];
[query2 whereKey:#"player1" notEqualTo:[[PFUser currentUser] objectForKey#"fbId"]];
PFQuery *mainQuery = [PFQuery orQueryWithSubqueries:#[query1,query2]];

Your player1 and player2 cols are strings containing user ids. I think this is going to cause other problems, but you can still do the query you're attempting as follows...
NSString *userId = [PFUser currentUser].objectId;
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"(player1 = 'UNDEFINED') AND (player2 != %#)", userId];
PFQuery *query = [PFQuery queryWithClassName:#"match" predicate:predicate];
EDIT - I changed fbId above to be the user's object id. That's what you're probably storing in the player string col. It's this kind of confusion that makes storing strings (instead of pointers) a problem for the design.

Related

How to set integer value in PFQuery where query?

I have integrated Parse in my iOS apps.
I want to know how can I set integer value in where query as below;
int userID =[[NSUserDefaults standardUserDefaults]valueForKey:#"USER_ID"];
PFQuery *querypush = [PFQuery queryWithClassName:#"EndCall"];
[querypush whereKey:#"UserId" equalTo:userID];
"UserId" column is of Number data type.
I can set string value but I can not set int value.
I have searched a lot but I could not find the solution.
Please help me to solve this issue.
You may get the user_id as a [PFUser currentUser].objectId] so you may set a query by following:
PFQuery *querypush = [PFQuery queryWithClassName:#"EndCall"];
[querypush whereKey:#"UserId" equalTo:[PFUser currentUser].objectId]];
You have to list the value as an object, which will mean an NSNumber in this case. Your code will look like this:
PFQuery *querypush = [PFQuery queryWithClassName:#"EndCall"];
[querypush whereKey:#"UserId" equalTo:#(userID)];
NSNumber can resolve to a lot of different primitive types, including int, but the Parse server needs the NSNumber type to resolve properly.

How to implement friend add/remove functionality in an iOS app using parse database?

I am trying to implement functionality to store data about user's friends (request friend, received friend request, accepted request). I have two tables.
First table is _User with username column.
Second table is Friends. This table is keeping track of who are friends of the user. This table has two fields:
A pointer column to user table
An array column called receivedRequest. In this array I keep the _User's objectId who are send request to that user.
Table _User has one to one relation with Friends table but meanwhile there is an array field keeping information of user's friend. In this array I am saving objectId of other users. I am using an array to avoid repeating rows for each friend's request.
Fist I want to know if this is a good idea or there is any alternative better that this. Actually I have extra array columns which is recived requests. Send requests. And accepted requests. All of them are array.
Second I want to know how can I write a query to go to Friends table. Find current user row. Go to friendList column. Return name of each friends whose name is in that array?
Currently I am doing this:
- (PFQuery *)queryForTable {
//Query user's friend request
PFQuery *query = [PFQuery queryWithClassName:#"Friends"];
[query whereKey:#"user" equalTo:[PFUser currentUser]];
[query includeKey:#"receivedRequest"];
return query;
}
This is returning only Id of the use's added my current user. I need their name from _User table.
Here's what I'd do:
(1) the User class ought to be about the user's relationship with the app, a place for data that's just between the user and the app.
(2) For data that users want to share, have a Persona class that has an image, nickname, etc. Persona should contain a pointer to User and vice versa.
(3) Personae (Personas in common usage) make friend invitations and become friends.
(4) arrays of string object ids = bad, arrays of pointers = good. In fact, I can't think of a circumstance where I'd prefer a string object id over a pointer.
(5) A FriendInvitation ought to be its own object, where inviter and invitee are pointers to Persona.
(6) A friendship is a bilateral and symmetrical relationship (at least we always hope they are). A good representation for that might be a Friendship class that has an array of pointers to exactly two Persona objects.
Here are a few functions, given a data model:
Persona has a pointer to User, call it 'user', and User has a persona pointer. FriendInvitation has an inviter and invitee, both pointers to Persona. Friendship has an array of two pointers to Persona, call it friends
// get the current user's FriendInvitations
- (void)friendInvitationsWithCompletion:(void (^)(NSArray *, NSError *))completion {
PFObject *persona = [PFUser currentUser][#"persona"];
PFQuery *query = [PFQuery queryWithClassName:#"FriendInvitation"];
[query whereKey:#"invitee" equalTo:persona];
[query includeKey:#"inviter"];
[query findObjectsInBackgroundWithBlock:completion];
}
// get the current user's friendships
// remember, these are not the friends, but the objects that record pairings of friends.
// see the next function for the friends
- (void)friendshipsWithCompletion:(void (^)(NSArray *, NSError *))completion {
PFObject *persona = [PFUser currentUser][#"persona"];
PFQuery *query = [PFQuery queryWithClassName:#"Friendship"];
[query whereKey:#"friends" equalTo:persona];
[query includeKey:#"friends"];
[query findObjectsInBackgroundWithBlock:completion];
}
// get the current user's friends' personae
- (void)friendsWithCompletion:(void (^)(NSArray *, NSError *))completion {
PFObject *persona = [PFUser currentUser][#"persona"];
[self friendshipsWithCompletion:^(NSArray *friendships, NSError *error) {
if (!error) {
NSMutableArray *result = [#[] mutableCopy];
for (PFObject *friendship in friendships) {
NSArray *friends = friendship[#"friends"];
NSInteger indexOfFriend = ([friends indexOfObject:persona] == 0)? 1 : 0;
[result addObject:friends[indexOfFriend]];
}
completion(result, nil);
} else {
completion(nil, error);
}
}];
}
// agree to be friends with someone
- (void)becomeFriendsWith:(PFObject *)friend completion:(void (^)(BOOL, NSError *))completion {
PFObject *persona = [PFUser currentUser][#"persona"];
PFObject *friendship = [PFObject objectWithClassName:#"Friendship"];
friendship[#"friends"] = #[ persona, friend ];
[friendship saveInBackgroundWithBlock:completion];
}
// we could go on, but this should convey the basic ideas
Friends table should not have arrays, but single IDs (actually pointers). So for every incoming request or friendship, there should be a single, separate entry on the database. So your Friends object (or for a better name, Relationship, or Friendship, but that's my personal preference of course) should roughly have following properties:
first (_User)
second (_User)
type (String. Possible values: 'friends' or 'request', maybe even 'blocked')
And for every accepted request, make sure you are creating two entries, one with first=user1/second=user2 and one with first=user2/second=user1. While you could technically go without making double entries, it will just complicate things in the long run, making everything harder to maintain.

How to Order by DateCreated with multiple OR condition in Parse

I have a requirement where i will be fetching data from a table using multiple 'OR' conditions in multiple columns, like either data in a column has to match or data in another column has to match for retrieving a row. And once this condition satisfied i need all the eligible objects to be ordered in their creation date(createdAt).
Here is what i am doing:
PFQuery *query1=[PFQuery queryWithClassName:#"Messages"];
[query1 whereKey:#"Receiver" equalTo:#"some-id"];
PFQuery *query2=[PFQuery queryWithClassName:#"Messages"];
[query2 whereKey:#"ThreadID" equalTo:#"some-threadID"];
PFQuery *finalQuery=[PFQuery orQueryWithSubqueries:#[query1,query2]];
[finalQuery orderByDescending:#"createdAt"];
NSArray *msgs=[query findObjects];
I am getting the messages but they are not lates, i.e. they are not sorted by 'createdAt'.
Can Anybody Help? Thanks

Parse.com query in 2 clases can it be done?

i want to query my location class but need to only return results posted by the user that has a certain data criteria.
in my user fields i have a column called customer i only want to return the posted locations of the user that has the customer column as NO
so it would go as follows
look for users > only get users that customer column = NO > List Those Location Posts > let the user chose one by showing the users display name ....
so it looks like i need to query 2 classes can i do this
i am using IOS 7 with Xcode 51 Beta3
My User class is as follows
username, displayName, Customer, DatePosted, DateUpdated
My Location Class is as follows
Location, PostedUser, DatePosted, DateUpdated
the PostedUser in the location class is linked to the User class
can this query be done?
i have tried but its not retuning anything for the label.text
// Create a query for places
PFQuery *query = [PFQuery queryWithClassName:#"Location"];
[query includeKey:#"postedUser"];
[query whereKey:#"displayName"
equalTo:[PFObject objectWithoutDataWithClassName:#"Location" objectId:_postedUser]];
NSLog(#"details from posted User %# .", _postedUser) ;
// Query 1
PFQuery * userQuery = [PFUser query];
[userQuery whereKey:"Customer" isEqual:#NO];
// Query 2
PFQuery * locationQuery = [PFQuery queryWithClassName:#"Location"];
// Make sure this key in locationQuery matches the objects from userQuery
[locationQuery whereKey:#"postedUser" matchesQuery:userQuery];
[locationQuery findObjects];
This should return all location objects where "postedUser" is a reference to a user whose "Customer" key = #NO.

How to Remove PFUser Current User from List Total User?

i'm using Parse.com I wanted to ask you something if you can ... How do I delete from the list the total number of users CurrentUser? I would avoid that the report will also be made with oneself: D Thank you all
Perfect Guys .. then I found the method ... In layman's terms to exclude the PFUser Current User from a query to show only the App users but not the CurrentUser is just the use of notEqualTo in the query but it should be associated with the string that we want to remove from the query
I hope this can help other people :)
Do not pay too much attention to the constants: D
PFQuery * query = [self.RelazioniUtenti query];
[query whereKey: FF_USER_NOMECOGNOME notEqualTo: [[PFUser currentUser] objectForKey: FF_USER_NOMECOGNOME]];
[query orderByAscending: FF_USER_NOMECOGNOME];
[query findObjectsInBackgroundWithBlock: ^ (NSArray * objects, NSError * error) {

Resources