parse.com objective-c get PfUser object and related object - ios

I am trying to get an object related to my user object. I've tried numerous methods...
this one gets the user object but I don't get the reputation object.
PFuserProfile = [PFQuery getUserObjectWithId:userObj];
PFuserRep = PFuserProfile[#"reputation"];
this one I have an error on the last line.
PFQuery *query = [PFUser query];
[query whereKey:#"objectId" equalTo:userObj];
[testQuery includeKey:#"reputation"];
NSArray *wtf = [query findObjects];
PFuserProfile = [wtf indexOfObject:0];
I've tried some other methods but not sure the best one, I can't get any of them to work... here's the last one where I get an error in setting the profile.
[query whereKey:#"objectId" equalTo:userObj];
[query includeKey:#"reputation"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if(!error){
PFuserProfile = [objects indexOfObject:objects.firstObject];
}
}];
Thank you.

Make sure that when you select an object from a dictionary use: objectAtIndex:
Therefore you will need to update your code to the following
PFQuery *query = [PFUser query];
[query whereKey:#"objectId" equalTo:userObj];
[testQuery includeKey:#"reputation"];
NSArray *wtf = [query findObjects];
PFuserProfile = [wtf objectAtIndex:0];
Better yet, because you can get an out of bounds exception with objectAtIndex: you can replace the last line with:
PFuserProfile = [wtf firstObject];
This will not crash your application if the query returned no objects.

Related

Query a table in Back4app

I have a User table in Back4app. I would like to query the table. I am using the below set of statement. It does not work. Please advise. The count always comes to zero.
PFQuery *query = [PFQuery queryWithClassName:#"User"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error){
NSLog(#"%lu", objects.count);
PFObject *obj = [objects firstObject];
NSLog(#"%#", obj);
NSString *str=[obj valueForKey:#"password"];
NSLog(#"%#", str);
}];
PFQuerys for PFUsers should be instantiated via [PFUser query]
So, you should replace this line
PFQuery *query = [PFQuery queryWithClassName:#"User"];
with this line
PFQuery *query = [PFUser query];
Hope this helps :)

Parse query finds two objects when there is only one

I have the following code to find the objects in a custom class. For some reason it is finding two of the same object (self.addedArray2's count is 2, but on Parse data table online, there is only one). Do you see why it is finding the same object twice?
self.array2 = [[NSMutableArray alloc] init];
self.addedArray2 = [[NSMutableArray alloc] init];
PFQuery *query = [PFQuery queryWithClassName:#"Friends"];
[query whereKey:#"user" containsString:[[PFUser currentUser] objectForKey:#"username"]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
for (Friends *currentFriend in objects) {
self.relation = currentFriend.friendsRelation;
self.addedRelation = currentFriend.addedRelation;
self.query = [_relation query];
[[_relation query] findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
[self.array2 addObjectsFromArray:objects];
[[_addedRelation query] findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
[self.addedArray2 addObjectsFromArray:objects];
[self.segmentControl setTitle:[NSString stringWithFormat:#"Friends (%lu)", (unsigned long)[self.array2 count]] forSegmentAtIndex:0];
[self.segmentControl setTitle:[NSString stringWithFormat:#"Added Me (%lu)", (unsigned long)[self.addedArray2 count]] forSegmentAtIndex:1];
NSLog(#"Number 1: %#", [self.addedArray2 objectAtIndex:0]);
NSLog(#"Number 2: %#", [self.addedArray2 objectAtIndex:1]);
}];
}];
}
}];
It is logging "Number 1" then "Number 1" then "Number 2". It looks like that code is being run twice and adding it again. How do I fix that? With all this nesting, I don't really see what I can do.
For your key "user" of the Friends class, if it String that holds the user's username, try replacing:
[query whereKey:#"user" containsString:[[PFUser currentUser] objectForKey:#"username"]];
with this and let me know if that changes anything:
[query whereKey:#"user" equalTo:[[PFUser currentUser] objectForKey:#"username"]];
If it is a pointer to a user object, however, then you will want your query to resemble something along these lines:
[query whereKey:#"user" equalTo:[User currentUser]];
If either of my assumptions are wrong, let me know because I do not know the structure of your classes, but I will try and figure it out.

IOS Parse is my nested query a good solution for comparing an object with a pointer?

Currently, I am querying the database twice to achieve a list of all users nearby who are not already being followed by the current user. Here is my nested query:
// List of all users being followed by the current user
PFQuery *followingActivitiesQuery = [PFQuery queryWithClassName:kFTActivityClassKey];
[followingActivitiesQuery whereKey:kFTActivityTypeKey equalTo:kFTActivityTypeFollow];
[followingActivitiesQuery whereKey:kFTActivityFromUserKey equalTo:[PFUser currentUser]];
[followingActivitiesQuery setCachePolicy:kPFCachePolicyNetworkOnly];
[followingActivitiesQuery includeKey:kFTActivityToUserKey];
[followingActivitiesQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSMutableArray *followedUserIds = [[NSMutableArray alloc] init];
// Obtain an array of object ids for all users being followed
for (PFObject *object in objects) {
PFUser *followedUser = [object objectForKey:kFTActivityToUserKey];
[followedUserIds addObject:followedUser.objectId];
}
PFGeoPoint *geoPoint = [[PFUser currentUser] objectForKey:kFTUserLocationKey];
// List of all users within 50 miles that are not already being followed
PFQuery *followUsersByLocationQuery = [PFQuery queryWithClassName:kFTUserClassKey];
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey notEqualTo:[PFUser currentUser].objectId];
[followUsersByLocationQuery whereKey:kFTUserLocationKey nearGeoPoint:geoPoint withinMiles:50];
[followUsersByLocationQuery whereKeyExists:kFTUserLocationKey];
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey notContainedIn:followedUserIds];
[followUsersByLocationQuery setLimit:100];
[followUsersByLocationQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.objects = objects;
[self.tableView reloadData];
}
}];
}
}];
My question is, is this a viable solution? I feel guilty about having to query the server twice in order to achieve this, but I was not able to do it all in one query. I could not compare a parse pointer from the ActivityClass to the Users class, since the Users class is the class being pointed to, and because of this I couldn't think of a way to do it all in one query.
You're in luck - this can be done in a single query using the whereKey:doesNotMatchKey:inQuery: method of PFQuery.
Parse will treat this as a single, compound query against the database. Totally guilt-free :)
Try this instead:
// List of all users being followed by the current user
PFQuery *followingActivitiesQuery = [PFQuery queryWithClassName:kFTActivityClassKey];
[followingActivitiesQuery whereKey:kFTActivityTypeKey equalTo:kFTActivityTypeFollow];
[followingActivitiesQuery whereKey:kFTActivityFromUserKey equalTo:[PFUser currentUser]];
[followingActivitiesQuery setCachePolicy:kPFCachePolicyNetworkOnly];
[followingActivitiesQuery includeKey:kFTActivityToUserKey];
PFGeoPoint *geoPoint = [[PFUser currentUser] objectForKey:kFTUserLocationKey];
// List of all users within 50 miles that are not already being followed
PFQuery *followUsersByLocationQuery = [PFQuery queryWithClassName:kFTUserClassKey];
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey notEqualTo:[PFUser currentUser].objectId];
[followUsersByLocationQuery whereKey:kFTUserLocationKey nearGeoPoint:geoPoint withinMiles:50];
[followUsersByLocationQuery whereKeyExists:kFTUserLocationKey];
//The next line is your new compound query
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey doesNotMatchKey:#"objectId" inQuery:followingActivitiesQuery];
[followUsersByLocationQuery setLimit:100];
[followUsersByLocationQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.objects = objects;
[self.tableView reloadData];
}
}];

Parse Query - cannot process more than one whereKey:doesNotMatchKey:inQuery

I was trying this
PFQuery *allDealsQuery = [Deal query];
PFRelation *favoritedDealsRelation = [user objectForKey:#"favoritedDeals"];
PFQuery *favoritedDealsQuery = [favoritedDealsRelation query];
PFRelation *redeemedDealsRelation = [user objectForKey:#"redeemedDeals"];
PFQuery *redeemedDealsQuery = [redeemedDealsRelation query];
[allDealsQuery whereKey:#"objectId" doesNotMatchKey:#"objectId" inQuery:favoritedDealsQuery];
//Parse does not support more than 2 where queries???
[allDealsQuery whereKey:#"objectId" doesNotMatchKey:#"objectId" inQuery:redeemedDealsQuery];
[allDealsQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
onSuccess(objects);
}
else {
onError(error);
}
}];
When I tried to use two queries, the answer was different from what was expected.
So should I use be using only one doesNotMatchKey query?
Try referencing parse documentation on Compound Queries:
https://parse.com/docs/ios_guide#queries-compound/iOS
Compound Queries
If you want to find objects that match one of several queries, you can use orQueryWithSubqueries: method. For instance, if you want to find players with either have a lot of wins or a few wins, you can do:
PFQuery *lotsOfWins = [PFQuery queryWithClassName:#"Player"];
[lotsOfWins whereKey:#"wins" greaterThan:#150];
PFQuery *fewWins = [PFQuery queryWithClassName:#"Player"];
[fewWins whereKey:#"wins" lessThan:#5];
PFQuery *query = [PFQuery orQueryWithSubqueries:#[fewWins,lotsOfWins]];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
// results contains players with lots of wins or only a few wins.
}];

how to query based on pfobject/pfuser associated with another pfobject in parse.com?

I have a Parse class called FriendRelation. This class has two users, one a friend the other a user.
I want to get all of the messages posted by all of the friends of a user. I am attempting to do so with the following query:
PFQuery *innerQuery = [PFQuery queryWithClassName:#"FriendRelation"];
[innerQuery whereKey:#"user" equalTo:currentUser];
PFQuery *query = [PFQuery queryWithClassName:#"Message"];
[query whereKey:#"userMessage" matchesQuery:innerQuery];
[query findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error) {
}];
This query comes back with no results.
I believe this is occurring because of the line:
[query whereKey:#"userMessage" matchesQuery:innerQuery];
The where key needs to be a FriendRelation to match. Is this correct?
How can I make the results of the inner query be a user that will intern match the matching query?
Thanks!
You can try using
- (void)whereKey:(NSString *)key matchesKey:(NSString *)otherKey inQuery:(PFQuery *)query
Something like:
PFQuery *innerQuery = [PFQuery queryWithClassName:#"FriendRelation"];
[innerQuery whereKey:#"user" equalTo:currentUser];
PFQuery *query = [PFQuery queryWithClassName:#"Message"];
[query whereKey:#"userMessage" matchesKey:#"firendUser" inQuery:innerQuery];
[query findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error) {
//do something useful..
}];
Let me know how it goes!

Resources