I have the following query:
PFObject *photoData = [PFObject objectWithClassName:#"Photos"];
PFRelation *relation = [photoData relationForKey:#"photo"];
PFQuery *query = [PFQuery queryWithClassName:#"People"];
query = [relation query];
[query whereKey:#"deleted" equalTo:#NO];
[query whereKey:#"createdAt" lessThan:_createdAt];
[query orderByDescending:#"createdAt"];
query.limit = 20;
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
...
}
I have a database table in Parse called People. In that table, there is a bunch of data but has a relation called photo. Now, I am saving one photo (with its data) in the photo relation. In the Parse dashboard, the data is saved correctly.
How do I fetch that back? Right now I have constraints on this system (and question) that each People objects has ONLY one photo object. So I need to fetch it all back at once.
Relation is just what its literal meaning is. It does not contain any data. If you want to query the data, you need to get the PFQuery from PFRelation by query method like so:
PFRelation *relation = [photoData relationForKey:#"photo"];
PFQuery *photoQuery = [relation query];
// perform your photoQuery here
If you limit them by one object only, then you can change your photo as Pointer type instead of using Relation.
Related
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 have a class named Circle with a relation named "members" to the _User class.
Class Circle:
Class _User:
I'm trying to query all Circles that the current user belongs to (inside the "members" relations).
PFUser *user = [PFUser currentUser];
PFRelation *relation = [user relationForKey:#"members"];
PFQuery *query = [relation query];
[query findObjectsInBackgroundWithBlock:^(NSArray *PF_NULLABLE_S objects, NSError *PF_NULLABLE_S error){
//objects size here is 0
//error is nil
}];
The problem is that the NSArray is empty and no error is received into the block.
One solution I'm thinking of is creating an actual table to store this relation and have a Relation column in both Circle and _User, but I believe there should be a better way to do this.
It doesn't appear that user has a members col. So, asking a user for its members relation is sure to fail. You want to query Circle...
PFQuery *query = [PFQuery queryWithClassName:#"Circle"];
[query whereKey:#"members" equalTo:user];
I am writing an iOS app and I am using Parse to store data on the server side.
I have Users and each user can have a Car.
I am trying to figure out how to write a query that allows me to get all users that have a car with year less than 2000 and with a certain color (lets say red).
Each car has a relationship to the user and each user also has a relationship to their car.
User <-> Car (one to one)
I started using the PFQuery:
PFQuery * userQuery = [PFQuery queryWithClassName:#"User"];
I am not sure how to handle the relationship in the query. So, I'm pretty much not sure how to get this done.
Any suggestion?
First off, the User class is a special case, when using it in a query you need to do this:
PFQuery *query = [PFUser query];
Next, the way you construct the query you want depends where the pointer is. If the User has a car property that is a pointer to the Car then the query would be as follows:
PFQuery *userQuery = [PFUser query];
PFQuery *carQuery = [PFQuery queryWithClassName:#"Car"];
[carQuery whereKey:#"year" lessThan:#(2000)];
[carQuery whereKey:#"color" equalTo:#"red"];
[userQuery whereKey:#"car" matchesQuery:carQuery];
[userQuery includeKey:#"car"]
[userQuery findObjectsInBackgroundWithBlock:^(NSArray *users, NSError *error) {
for (PFObject *user in users) {
PFObject *car = user[#"car"];
// read user/car properties as needed
}
}];
If instead the Car class has a user property you just do a normal query and add the following line to let you access the full User object:
[carQuery includeKey:#"user"];
What does your table look like? If you have User as a column in your Car table, you can just query the car table for cars of year less than 2000 and then you would just access the User property of that query. It would look something like this:
PFQuery *carQuery = [PFQuery queryWithClassName:#"Car"];
[carQuery whereKey:#"year" lessThan:#(2000)];
[carQuery includeKey:#"user"];
[carQuery findObjectsInBackgroundWithBlock:^(NSArray *cars, NSError *error) {
if (!error) {
for (Car *car in cars) {
User *user = car#["user"];
}
}
}];
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"];
I am having two queries one is friendsrequestQuery and other is user query i want to add all the data of friendrequestQuery details into user query while fetching data from the user Query.
NSPredicate *predicate12=[NSPredicate predicateWithFormat:#"((UserFriendId == %# )AND (UserId!=%#)) OR ((UserFriendId != %# )AND (UserId==%#)) ",#"Nwk44aeSrz",#"Nwk44aeSrz",#"Nwk44aeSrz",#"Nwk44aeSrz"];
PFQuery *innerQuery = [PFQuery queryWithClassName:#"FriendsDetails" predicate:predicate12];
[innerQuery whereKey:#"BlockStatus" equalTo:#"No"];
PFQuery * userQuery = [PFUser query];
[userQuery whereKey:#"objectId" matchesKey:#"UserFriendId" inQuery:innerQuery];
[userQuery whereKey:#"objectId" matchesKey:#"UserId" inQuery:innerQuery];
[userQuery whereKey:#"objectId" notEqualTo:#"Nwk44aeSrz"];
I wil explain the thing what i need exactly is, in innerquery table i am having 10 columns but i need the data of these particular coloum data converstionid,lastmessage,lastdate while reterving the data of users query.
Now i am getting the details of userquery but not the details of innerquery,so i need the details of Innerquerydetails .
Please help me .
I think you'd be better off storing pointers as opposed to Id's, this way you can include that data as well.
I will not use predicates, I realize your query is cleaner with predicates, but I think the logic is easier to see with this. You can convert it back to predicate for yourself.
// get your user
PFUser * userForQuery; // set up your user for the query, if it's current user, = [PFUser currentUser];
// first part of predicate
PFQuery * innerQueryA = [PFQuery queryWithClassName:#"FriendsDetails"];
[innerQueryA whereKey:#"UserFriend" equalTo:userForQuery]; // from #"UserFriendId"
[innerQueryA whereKey:#"User" notEqualTo:userForQuery]; // from #"UserId"
// second part of predicate
PFQuery * innerQueryB = [PFQuery queryWithClassName:#"FriendsDetails"];
[innerQueryB whereKey:#"userFriend" notEqualTo:userForQuery]; // from #"UserFriendId"
[innerQueryB whereKey:#"user" equalTo:userForQuery]; // from #"UserId"
// combine
PFQuery * query = [PFQuery orQueryWithSubqueries:#[innerQueryA, innerQueryB]];
[query whereKey:#"BlockStatus" equalTo:#"No"];
// Now, as you remember, we are storing a pointer in #"User" as opposed to an id #"UserId" as you had it. Because of
// this, we will use parse's includeKey: feature.
[query includeKey:#"User"]; // tells the query to include the data associated with these keys;
NSMutableArray * usersRetrieved = [[NSMutableArray alloc]init];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// objects will contain all of your objects
for (PFObject * object in objects) {
[usersRetrieved addObject:object[#"User"]]; // all the data should be available for the #"User" object
}
// objects will contain all the #"friendDetails" objects
// usersRetrieved will contain all the #"User" objects
}
else {
}
}];
I realize this changes your data structure a little bit, but it should give you all of the data you need.