PFQuery Matches Query not Working Parse.com - ios

Hello everyone I'm trying to merge two queries with MatchesQuery but the data on the TableView will not be displayed and gives me this error
Error: bad type for $ inquery
Does anyone know what is the error in this query? Thanks to all
- (void) retrieveFromParse {
PFQuery *Amici = [PFQuery queryWithClassName:#"Amicizie"];
[Amici whereKey:#"RICHIESTA_IN_ATTESA" equalTo:#"YES"];
PFQuery *retrievePets = [PFQuery queryWithClassName:FF_USER_CLASS];
[retrievePets whereKey:FF_USER_NOMECOGNOME matchesQuery:Amici];
[retrievePets orderByAscending:FF_USER_NOMECOGNOME];
[retrievePets findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"%#", objects);
allObjects = [[NSMutableArray alloc] init];
for (PFObject *object in objects) {
[allObjects addObject:object];
}
}
[self.FFTableViewFindUser reloadData];
}];
}

Given that you are querying on a boolean value, you should look at this question.
Basically you need to do this:
[Amici whereKey:#"RICHIESTA_IN_ATTESA" equalTo:[NSNumber numberWithBool:YES]];
That may be all you need. If not it will get you another error message to help you get to the root of the issue.

You can add a "amiciString" column which holds the string value. Then you can do this:
[retrievePets whereKey:#"FF_USER_NOMECOGNOME" matchesKey:#"amiciString" inQuery:Amici];
Try! I hope it works!

Related

Why is my NSMutable not being populated correctly when inserting objects from another NSArray?

I have a PFQuery that gets the current participants of a particular event:
PFQuery *getcurrentparticipants = [PFQuery queryWithClassName:#"Event"];
[getcurrentparticipants selectKeys:#[#"Participants"]];
[getcurrentparticipants whereKey:#"objectId" equalTo:ObjectID];
[getcurrentparticipants findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSMutableArray *newParticipantsArray = [[NSMutableArray alloc]init];
if([objects[0] valueForKey:#"Participants"] == nil){ // If object retrieved in objects is null. If there are 0 participants
[newParticipantsArray addObject:PFUser.currentUser.username];
PFQuery *query = [PFQuery queryWithClassName:#"Event"];
[query getObjectInBackgroundWithId:self.ObjectID
block:^(PFObject *Event, NSError *error) {
Event[#"Participants"] = newParticipantsArray;
[Event incrementKey:#"Vacants" byAmount:[NSNumber numberWithInt:-1]];
[Event saveInBackground];
}];
}else{ // STEP 5
for(int i=0;i<objects.count;i++) {
[newParticipantsArray addObject:[[objects objectAtIndex:i] valueForKey:#"Participants"]];
}
[newParticipantsArray addObject:PFUser.currentUser.username];
NSLog(#"Part to upload %#", newParticipantsArray);
PFQuery *query = [PFQuery queryWithClassName:#"Event"];
[query getObjectInBackgroundWithId:self.ObjectID
block:^(PFObject *Event, NSError *error) {
Event[#"Participants"] = newParticipantsArray;
[Event incrementKey:#"Vacants" byAmount:[NSNumber numberWithInt:-1]];
[Event saveInBackground];
}];
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
This is how the method works:
Create a PFQuery object
Query the Participants Class for an specific ObjectId
If no error, then we create a NSMutable array
If no participants are in Parse then we insert the current user as participant.
Else, insert all participants in the mutable array and add currentuser at the end of the array.
Then upload it again to Parse
My problem is in step 5:
When I perform the tasks in the else, the column in Parse looks like this :
[["Participant 1"],"Participant 2"]
But I would like to have it like this:
["Participant 1","Participant 2"]
What I have tried:
I tried things like putting the arrays like this. [newParticipantsArray addObject:[[objects objectAtIndex:i] valueForKey:#"Participants"]]; and similar combinations, of course without luck.
It’s hard to say for sure since I can’t see the structure of your data but are you sure the value held in
[[objects objectAtIndex:i] valueForKey: #“Participants”]
Is a single user and not itself an array of users? The plural key “participants” seems to suggest it’s an array of users which would also explain the result you’re getting.
If in fact the value returned for the "Participants" key is an array, you can add the objects in it to your mutable array by doing the following:
NSArray* participants = [[objects objectAtIndex:i] valueForKey:#"Participants"]
[newParticipantsArray addObjectsInArray:participants];
This uses the addObjectsInArray: method of NSMutableArray to add the objects from the old array into the new one.

Load column form parse in to an Array

I am working on a little app with parse.com. I want to download all objects from a column (Array) called "Firstname". I found some code, but when I log "object" it shows the class completely:
PFQuery *query = [PFQuery queryWithClassName:#"Name"];
[query selectKeys:#[#"Firstname"]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
NSLog("%#", objects);
}];
Edit:
PFQuery *query = [PFQuery queryWithClassName:#"Name"];
[query selectKeys:#[#"Firstname"]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
self.FirstnameArray = [objects valueForKey:#"Firstname"];
NSLog(#"%#", self.FirstnameArray);
[self.myTableView reloadData];
}];
A query always returns objects of the class associated with the query. Using selectKeys just limits the data that comes back.
You can extract an array of just the values from the returned array with:
NSArray *values = [objects valueForKey:#"Firstname"]
Thats normal, you will get back the whole object - aka a row from that class you are performing the query on. If I recall correct, SelectKey will return any associated object - ie a relation object. So in your case you do not need to use select.

(parse) getting error when updating pfobject

However simple it may be, I am still struggling to update PFObject data with
-(IBAction)postMessageTapped:(id)sender{
[self hideTextField:_messageTextField];
NSMutableArray *myNewMessageArray=[[NSMutableArray alloc]init];
[myNewMessageArray insertObject:_messageTextField.text atIndex:0];
[myNewMessageArray insertObject:[PFUser currentUser] atIndex:1];
PFQuery *query = [PFQuery queryWithClassName:ClassName];
[query getObjectInBackgroundWithId:currentId block:^(PFObject *object, NSError *error) {
object[messagingArray] = myNewMessageArray;
[object saveInBackground];
}];
}
The intent is to get message string from text field and current user name, and put that into an array which then updates the array that exists on the parse database. However,
Cannot do a comparison query for type: (null)
comes up when the user taps the button that posts the message.
Does anyone have a possible solution?
Edit:
PFQuery *query = [PFQuery queryWithClassName:ClassName];
[query whereKey:#"location" nearGeoPoint:locationOfSelectedPin];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!objects) {
NSLog(#"The getFirstObject request failed.");
} else {
for(PFObject *objectTest in objects){
NSLog(#"Successfully retrieved the object.");
objectTest[#"messagingArray"]=myNewMessageArray;
[objectTest saveInBackground];
}
}
}];
I have also tried using this to update my data, 'successfully retrieved object' gets printed 3 times, but then that is followed by three lines of 'error, object not found for update'.
Check where you are setting objectId - this error means it cannot get the object because you are passing a nil value to the database for lookup.
Here's a bit of code to handle the exception:
if (!currentId) {
NSLog(#"Your currentId object is nil! Check your assignment.");
}
else {
PFQuery *query = [PFQuery queryWithClassName:ClassName];
[query getObjectInBackgroundWithId:currentId block:^(PFObject *object, NSError *error) {
object[messagingArray] = myNewMessageArray;
[object saveInBackground];
}];
}

Query on Parse relational data is not coming back ordered using orderedByAscending

I'm querying relation data on parse and I would like the objects to come back ordered by the date they were created. I've had this method work before but haven't been able to get an ordered query using relational data. The query return is in a random order. Thanks in advance! Here's my code:
PFQuery *postQuery = [PFQuery queryWithClassName:#"Post"];
[roomQuery whereKey:#"name" equalTo:self.postName];
NSError *error;
//done on main thread to have data for next query
NSArray *results = [postQuery findObjects:&error];
PFObject *post;
if ([results count]) {
post = [results objectAtIndex:0];
NSLog(#"results were found");
} else {
NSLog(#"results were not found");
}
PFRelation *commentsRelation = [#"Comments"];
[commentsRelation.query orderByAscending:#"createdAt"];
[commentsRelation.query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error Fetching Comments: %#", error);
} else {
NSArray *comments = objects;
}
I'm a little confused by your code,
you create a "postQuery", and call it, but never use any of its data.
There's also a roomQuery that never seems to have been allocated, or used.
You're querying a specific post by its name. Are you controlling its name? If not, you should use id's
what is PFRelation commentsRelation = [#"Comments"];
Probably because it's just a snippet, this stuff is dealt with elsewhere; however, for my answer, I'm assuming that your "comments" field is an array of "Comment" class objects.
Option 1:
PFQuery * postQuery = [PFQuery queryWithClassName:#"Post"];
[postQuery whereKey:#"name" equalTo:self.postName];
// again, possibly an id field would be more reliable
// [postQuery whereKey:#"objectId" equalTo:self.postId];
[postQuery includeKey:#"Comments"];
PFObject * post = [postQuery getFirstObject];// no need to download all if you just want object at [0]
// this will contain your post and all of it's comments with only one api call
// unfortunately, it's not sorted, so you would have to run a sort.
NSArray * comments = [post[#"Comments"] sortedArrayUsingComparator: ^(id obj1, id obj2) {
return [obj1[#"createdAt" compare: obj2[#"createdAt"];
}];
Option 2:
Perhaps a better option is to rework your data structure and instead of associating the comments to the post, you could associate the post to the comments (as in the parse docs)
PFQuery * postQuery = [PFQuery queryWithClassName:#"Post"];
[postQuery whereKey:#"name" equalTo:self.postName];
// again, possibly an id field would be more reliable
// [postQuery whereKey:#"objectId" equalTo:self.postId];
PFQuery * commentQuery = [PFQuery queryWithClassName:#"Comment"];
[commentsQuery whereKey:#"parent" matchesQuery:postQuery]; // when creating a comment, set your post as its parent
[commentsQuery addOrderDescending:#"createdAt"]
[commentQuery findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error) {
// comments now contains the comments for myPost
}];
Both of the above solutions avoid making extra unnecessary api calls (parse charges based on calls after all!).

Ios- Parse.com delete an object

I think I'm overcomplicating this scenario. I'm working through a join table in a many to many situation.
If I find a join, I want to delete it, if I don't find one, I want to add it.
Adding a new join works fine. I can't figure how to delete ..
This is my code. If anyone sees anything wrong - or a better way to do this, please advise.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%s", __FUNCTION__);
//Create query for all current user objects
PFQuery *query = [PFQuery queryWithClassName:#"DDPeopleJoin"];
[query whereKey:#"parseUser" equalTo:[PFUser currentUser]];
[query whereKey:#"serviceKey" equalTo:[currentService valueForKey:#"serviceKey"]];
[query whereKey:#"personKey" equalTo:[currentPerson valueForKey:#"personKey"]];
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
// Run the query - if there is an object delete it otherwise, go to JoinPeople
allDeadPeople = [NSMutableArray new];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
if (!objects) {
NSLog(#"New Person");
[self joinPeople];
return;
}
NSLog(#"Found a match, erase them");
for (PFObject *object in objects) {
[object deleteInBackground];
}
[self refreshJoins:self];
}
}];
}
Firstly, instead of using enumerate block to delete each object, you can use the following:
[PFObject deleteAllInBackground:objects];
Secondly, You might get trouble with [self refreshJoins:self coz it will run before all object can be deleted. You should put that in the -deleteInBackground:block to make sure [self refreshJoins:self]` works properly

Resources