query not returning the latest objects - ios

I'm using Parse within my app. i'm trying to do a query with a limit of 10 objects ordered by descending order of the createdAt property plus I'm using the nearGeopoint:WithinKilometers function. When i run the query, the receive the oldest objects in the database. when i remove the limit of number of objects to be returned, the query returns the latest objects from the newest to oldest (as expected). does the limit do that? isn't it a bug? here is the code, please let me know if there is anything wrong:
PFQuery *postsQuery = [PFQuery queryWithClassName:#"user_p"];
if (city)
{
[postsQuery whereKey:#"geoPoint" nearGeoPoint:[PFGeoPoint geoPointWithLatitude:[city[#"latitude"] doubleValue] longitude:[city[#"longitude"] doubleValue]] withinKilometers:[[[NSUserDefaults standardUserDefaults] valueForKey:#"distanceCovered"] doubleValue]];
}
[postsQuery orderByDescending:#"createdAt"];
[postsQuery includeKey:#"user_id"];
[postsQuery whereKeyExists:#"user_id"];
[postsQuery setLimit:10];

Related

PFQuery Mixing nearGeoPoint with Bool

When I run the following
PFQuery *query = [PFQuery queryWithClassName:#"EventsTable"];
[query setCachePolicy:kPFCachePolicyNetworkOnly];
// Only active items
[query whereKey:#"active" equalTo:[NSNumber numberWithBool:YES]];
// Query by distance from current location
[query whereKey:#"geoLocation" nearGeoPoint:currentLocation];
// Only download objects that match the appropriate key
[query whereKey:#"keyedItems" containedIn:keysArray];
[query findObjectsInBackgroundWithBlock:^(NSArray *eventArray, NSError *error) {
It goes into an infinite loop with no error messages. But If I drop the nearGeoPoint it works fine, or if I keep the nearGeoPoint but drop the active it also works. But dropping the containedIn and keeping the nearGeoPoint and the active also fail the same way. I have also tried rearranging the order but no luck.
Any suggestions?
At first I wasn't able to find an error message so I assumed that it was stuck in the block, but alas here it is
Error: Error Domain=Parse Code=1 "{"code":1,"message":"Internal server error."}" UserInfo={error={"code":1,"message":"Internal server error."}, NSLocalizedDescription={"code":1,"message":"Internal server error."}, code=1} {
NSLocalizedDescription = "{\"code\":1,\"message\":\"Internal server error.\"}";
code = 1;
error = "{\"code\":1,\"message\":\"Internal server error.\"}";
}
This sounds like a parse server error to me - Is that correct?
The issue is that the table was so large it was unable to handle the query. The fix was just as mentioned above - to create an index. In this case I was able to turn on automatic indexing in the MongoDB. That solved the problem.

Pagination With Dynamic Content

I'm trying to figure out the proper way to paginate results using the Parse SDK for iOS. The problem I'm having is that the content I'm trying to paginate has the potential to change frequently.
For example:
There is an app with a bunch of objects stored on a server, and the request to get these objects is sorted with newest first and paginated in case there are a lot of objects. When the user scrolls, as they are approaching the last object on the current page, the next page gets requested.
Say the user scrolls to page two, then a new object is added to the list of objects, and the user then scrolls up another page. When the next page is requested, they will get a duplicate of the last message on the second page, and since page 0 has already been loaded, the new object won't be displayed.
How can something like this be handled?
How would the implementation change if the objects were sorted oldest first?
Thanks in advance for the help.
Edit: request pseudo code
- (void)fetchObjectsForPage:(NSUInteger)page completion:(void (^)(NSArray *_Nullable objects, PageInfo *_Nullable pageInfo, NSError *_Nullable error))completion{
PFQuery *query = [SomeObject query];
[query orderByAscending:#"updatedAt"];
[query setLimit:50];
[query setSkip:50 * page];
[query findObjectsInBackgroundWithBlock:^{NSArray *_Nullable objects, NSError *_Nullable error){
...
>>> Do error checking and return array along with paging info (total number of objects, page size) or error in completion block.
}];
}
It's not the request I'm having trouble with, it's figuring out how to properly handle paging in the table when a new object gets added.
What you can do is the following:
Create a query that will return 50 rows (like you did) order by updatedAt
When you get result take the last item from the list and save the item updatedAt in some global property
In the next call do not use setOffset but get the next 50 rows and add another condition of where updatedAt is greater than the updatedAt of your global object. This way you make sure that you will not have duplicate records in your list
At the end your code should look like the following:
PFQuery *query = [PFQuery queryWithClassName:#"SomeClassName"];
[query orderByAscending:#"updatedAt"];
[query setLimit:50];
if (self.lastItemUpdatedAt){
[query whereKey:#"updatedAt" greaterThan:self.lastItemUpdatedAt];
}
[query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
if (objects.count > 0){
self.lastItemUpdatedAt = [[objects lastObject] updatedAt];
}
}];
Now if you use updatedAt there is a chance that you will still get duplicates because let's assume that someone change the object so the updatedAt will also be changed (so it will be greater than the updatedAt that you saved) in this case you can use createdAt instead of updatedAt since createdAt will never be changed

Parse - multiple condition queries issue in xcode (objective-c)

I'm using the parse backend to be database of my apps in Xcode (objective-c), but I don't know how to write a multiple condition parse format query. I want to convert the below query to a parse format query in the Xcode.
$msg_record = $this->db->query('SELECT msg, send_id, send_time FROM msg_record
WHERE (send_id=123456789 AND to_id=987654321) OR (send_id=987654321 AND to_id=123456789)
ORDER BY send_time ASC')->result();
Can anybody help me to convert the query? Thanks.
To create an or condition in a Parse query, you will have to make two (or more) subqueries which you merge with the orQueryWithSubqueries.
Be aware that you cannot translate SELECT directly from SQL to Parse.
This is what you are looking for:
PFQuery *query1 = [PFQuery queryWithClassName:#"msg_record"];
[query1 whereKey:#"send_id" equalTo:#"123456789"];
[query1 whereKey:#"to_id" equalTo:#"987654321"];
PFQuery *query2 = [PFQuery queryWithClassName:#"msg_record"];
[query2 whereKey:#"send_id" equalTo:#"987654321"];
[query2 whereKey:#"to_id" equalTo:#"123456789"];
PFQuery *mainQuery = [PFQuery orQueryWithSubqueries:#[query1,query2]];
[mainQuery orderByAscending:#"send_time"];

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

PFQuery constraints - exclude subquery

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.

Resources