parse web service relational database - ios

I am using parse to develop an iOS app.
For the database, I have three tables, named user, UserAndCourse, and course.
Where UserAndCar stores a pointer to user and course.
the tables looks like:
My problem is:
How can I query the courses that belongs to the current user on iOS. i.e that look into UserAndCourse to find the rows that user column is current user and query for the course object that is pointed to by the course column.
Can I do this in a single relational query? or I have to query the UserAndCourse table rows first and then query the course it pointed to.

I suggest to use PFRelation, that way you don't need to create new table for relations like userAndCourse. Parse automatically will link through the relation. You just need to create relation between them and do what you want.
Saving relation;
PFUser *user = [PFUser currentUser];
PFRelation *relation = [user relationForKey:#"course"];
[relation addObject:coursePFObject];
[user saveInBackground];
And query when you need to reach them;
PFRelation *relation = [user relationForKey:#"course"];
PFQuery *query = [relation query];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
// results contains all the people who subscribe to course
}];
Moreover you can specify your course by adding more queries on it;
PFQuery *query = [relation query];
[query whereKey:#"name" equalTo:#"Math"];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
// results contains all the people who subscribe Math course
}];
I think it's better way to shape your tables in parse. Otherwise you need to create table for each relation.
Hope it helps also if you need more detail this can be helpful.

Related

How do I fetch all relation objects in Parse.com IOS?

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.

How to retrieve array field from "User" table and get records from other table? parse

I have 3 tables on parse
User table - has users and lists they follow
List table - has user created list
Message table - pointers to record from List table
A user may follow multiple list, so all the list id's are stored as array of object id's corresponding to records in list table
When I call
NSArray *convArr = [[PFUser currentUser] objectForKey:#"lists"];
it shows there is list object, but it looks as if empty and I cannot retrieve values from it to further query list table to get the lists user is following
For all the users and their list I have
PFQuery *uQuery = [PFUser query];
[uQuery includeKey:#"lists"];
[uQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
...
}];
but I can't pass current user information in the query.
[uQuery whereKey:#"user" equalTo:[PFUser currentUser]]; or
[uQuery includeKey:[PFUser currentUser].objectId];
Adding any of this doesn't pull up records for the current user.
You could try refreshing the current user so the latest data is pulled from the server, and then looking at the lists object.
[[PFUser currentUser] fetchInBackgroundWithBlock:^(PFObject *user, NSError *error){
NSArray *convArr = [user objectForKey:#"lists"];
}];
Okay, I'm going to try it anyhow.
I'm going to assume you have a currentUser you want to retrieve all their lists for. You could do a simple query like this (Ofcourse assuming you have an array with objectIds of the lists he made):
PFQuery *query = [PFQuery queryWithClassName:#"List"];
[query whereKey:#"objectId" containedIn:currentUser[#"lists"];
[query findObjectsInBackgroundWithBlock:^(NSArray *lists, NSError *error) {
//This should return all the lists based on the keys inside the column of lists from the current User
}
If you want to do this for every User you'd have to query the user first, then basically do the same thing but instead of user "currentUser[#"lists"]", you'd use something similar like "queriedUser[#"lists"]". Pardon me in advance for the horrible syntax.
Also one handy tool for finding the right "querying constraints" might be this link
I hope this atleast has helped you a bit!

Parse.com Following / Follower Logic

Having some trouble trying to figure out some logic for the following situation.
I have built a friends system for my mobile app using parse. Simply put, when a user "follows" something they are put into a relationship. That relationship contains all of the people that the individual user has folowed.
User
Relationship - Friends (contains all of the users that that overall user has followed)
I can query who an individual user is following fairly easily:
PFQuery *query = [PFUser query];
[query whereKey:#"username" equalTo:#"asg"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
for (PFObject *object in objects) {
PFRelation *friendsRelation = [object objectForKey:#"Friends"];
PFQuery *query = [friendsRelation query];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"%#", objects);
} else {
}
}];
}
}];
How would I query who is following a certain user, though? So, a users followers.
If you already know the user, use whereKey:equalTo::
PFObject *user = ...;
PFQuery *query = [PFUser query];
[query whereKey:#"Friends" equalTo:user];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
If you need to do a query to get the user then instead combine the requests with whereKey:matchesQuery::
[query whereKey:#"Friends" matchesQuery:userQuery];
I actually did a bunch of blog posts talking about implementing a friends list that might help you:
Overview
JavaScript part 1
JavaScript part 2
JavaScript part 3
The code samples are in JavaScript, but shouldn't be too hard to convert to iOS.
It covers the relationships, querying, updating etc.
The short answer to your question it to use a Join Table instead of a Relation so you can easily query from both sides of the relationship.
You can find a lot of information in the relations guide on the Parse site:
https://parse.com/docs/relations_guide#manytomany-jointables
I think what you are asking for is the PFUser *user = [PFUser currentUser] method. If you are trying to retrieve friends for the current user logged in. You could use the same for retrieving the users that the current user logged in has followed.

Parse iOS how query object by properties found in related PFObject?

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"];
}
}
}];

Get a PFUser details who are not current user

I am using the Parse framework and have it set up where I can login and access the user who logs in PFUser object. I want to be able to visit a friends page and to do this i need to query and retrieve data (names and other pieces of information) of a PFUser object which is not the on that is logged in. I cannot find any queries that let me access data from the User class. I hope this makes sense,
Thanks
It really depends on what sort of criteria you want to search on, but you can query PFUsers just like you would any other PFObject within Parse. The only difference is that you create your query with the +[PFUser query] method. Here's an example from Parse's documentation:
PFQuery *query = [PFUser query];
[query whereKey:#"gender" equalTo:#"female"]; // find all the women
NSArray *girls = [query findObjects];
You can also query where a user is an associated object on some other class in Parse, and you can also handle results asynchronously:
PFQuery *query = [PFQuery queryWithClassName:#"Post"];
[query whereKey:#"user" equalTo:user];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
// do something with results
}];
Check out the query documentation for other examples of the sorts of things you can do with queries.

Resources