Why can not access to pointer object of _User in Parse? - objective-c

I have a table called "Event" with public read and write access.
Inside this table I have one field called "user". This field is a pointer to _User table with public read and only user write access.
This is my code:
PFQuery *query = [PFQuery queryWithClassName:#"Event"];
[query whereKey:#"objectId" equalTo:self.objID];
[query getObjectInBackgroundWithId:self.objID block:^(PFObject *object, NSError *error) {
if (!error)
{
PFUser *host = [object objectForKey:#"user"];
NSLog(#"HOST == %#",host);
self.hostId = host.objectId;
}
]);
Now problem is, if userA create a row in Event table called eventA and userB create an Event called eventB. if UserA query eventB cannot access to userB information. However, if userA query eventA, it can access to itself information.

Answer is pretty much easy. It seems that I need to include key in my query:
[query includeKey:#"user"];

Related

Parse.com combine nested query

I am new to using parse, and currently adding parse to an app that uses SOAP web services to replace them.
Now I come a little stuck, as due to having it done in MySQL and php I am trying to translate the logic from the tables and code to parse.
I have a function that I have written and it achieves exactly what I am after, however I just think its wrong and can be done better, for starters I am not calling findObjectsInBackground, which I know I need to.
I am trying to take this result and then reload a tableView.
NSMutableArray *activityfeed = [NSMutableArray new];
//get current user
PFUser *user = [PFUser currentUser];
if (user != nil) {
PFQuery *query = [PFQuery queryWithClassName:#"Event"];
//get event that user is involved in
[query whereKey:#"invited" equalTo:user];
//get the events
NSArray *events = [query findObjects];
//loop over the events
for (PFObject *event in events) {
//owner is a pointer to the users class
PFUser *owner = event[#"owner"];
if (![user.objectId isEqualToString:owner.objectId]) {
//ignore the info for the logged in user for now
//invited is a relation so one event has many users
PFRelation *relation = [event relationForKey:#"invited"];
PFQuery *query = [relation query];
[query orderByDescending:#"dateinvited"];
[query addDescendingOrder:#"dateaccepted"];
//get the friends that are involved with the event
NSArray *friends = [query findObjects];
for (PFUser *friend in friends) {//Perform logic checks here and then add to activityfeed}
}
}
}
return activityfeed;
So my logic above gets the current user, then get all the events that user is involved with, then get all the other people involved with that event and then work out what to display.
Is there a more efficient way of doing the above?
Usually we use whereKey:matchesQuery in cases like this. Take some research on this.
This question may help you find out some solution.

Parse.com Store data from one object into another object

I'm creating an app using parse as the backend, I have three Classes (User,Student,School). I currently have a pointer between the User class and the Student Class so if I enter a new student I can create a relation to the User.
My issue is I am trying to do the same for the School class, this class is a pre-populated class and when I am creating a new student I need to reference that class by school_id that is in the student class as a pointer.
images of my class are
So from the images you can see that the object_id from the user class is the parent_id in the students class. Now I need to have the object_id or school_id from the School class as the school_id in the Student Class.
Expected results:
User"jamiemw" -> Student"johnnie Williams" -> School"Southwind"
below is what I've tried with
PFObject *kid = [PFObject objectWithClassName:#"Kids"];
kid[#"child_name"] = #"Johnnie Williams";
kid[#"age"] = #"14";
kid[#"date_of_birth"] = #"02/27/2001";
[kid setObject:[PFUser currentUser] forKey:#"parent_id"];
//this is what does not work.
[kid setValue:[PFQuery queryWithClassName:#"Schools"] forKey:#"student_id"];
[kid save];
PFQuery *query = [PFQuery queryWithClassName:#"Kids"];
[query whereKey:#"parent_id" equalTo:[PFUser currentUser]];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error)
{
for(int i = 0; i <= results.count; i++){
NSLog(#"%#", [results objectAtIndex:i]);
}
}];
Your first problem is that [PFQuery queryWithClassName] returns a PFQuery, as shown in the documentation. Storing this instance of a query is probably not going to give you any useful information, so you will want to first perform the query you instantiated and extract the desired data from that before saving it to a key in the kid PFObject.
The second problem I noticed is that there doesn't appear to be a key student_id for any of the tables you posted screenshots of above. I'm assuming this was a typo and you meant to write [kid setValue:[PFQuery queryWithClassName:#"Schools"] forKey:#"school_id"];
Replacing the above mentioned line of code with the following should achieve the desired result:
[PFQuery queryWithClassName:#"Schools"];
[query whereKey:#"school_id" equalTo:#"southwindE123"];
// getFirstObject can be used here because school_id
// is assumed to be a unique key
PFObject *school = [query getFirstObject];
[kid setValue:school forKey:#"school_id"];

Parse: Remove user when session ends?

I was wondering if it were possible to remove a user completely from the database if their session ends? Maybe in sign up, I can check if there is a session for the username the person is using and if there isn't, it deletes the previous user and registers a new one?
How do I check if there is a current session for a certain username?
UPDATE:
PFQuery *query = [PFQuery queryWithClassName:#"Friends"];
[query whereKey:#"username" equalTo:[[PFUser currentUser] objectForKey:#"username"]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
for (Friends *currentFriend in objects) {
[currentFriend deleteInBackground];
}
}];
You can either:
1. [Recommended] Use a anonymous user to begin with, Reference can be found here.
2. In AppDelegate.m - applicationWillTerminate: method, you can do
[user deleteInBackground];
[PFUser logOut];
This will delete your logged in user permanently, locally and from remotely.
To
check if a session has a certain username
, all you need to do is:
PFUser user = [PFUser currentUser];
if ([user.objectId isEqualToString:"myTargetUserId"]) {
NSLog("Target user exists");
}

Correct way to user PFQuery to query relational data like Pointer

Ok so let's say I have a post of an event, and users can click a button to notify that they are attending this event. As of now I have a class called Activity in which I save the current user and the event to this class, so theres 2 columns. If I want to query all users who are attending an event, am I headed in the right direction to do this, or am I doing it complentely wrong?
So far I have:
-(PFQuery*)queryForTable {
PFQuery *activityQuery = [PFQuery queryWithClassName:#"Activity"];
[activityQuery whereKey:#"event" equalTo:self.event];
[activityQuery includeKey:#"going"];
return activityQuery;
}
cellForRowAtIndex:
UILabel *title = (UILabel*) [cell viewWithTag:1];
title.text = [object objectForKey:#"going.username"];
You can actually see what you have been done in the Parse dashboard. That's also their purpose to develop a data browser like this. It's way more convenient.
For your case, you just need to check whether the type is Pointer. Try to click on that if so in the dashboard. It will direct you to the target object.
Would suggest you to read this article first, it's about the relation:
https://parse.com/docs/relations_guide
Then, you should go check the iOS SDK tutorial:
includeKey is definitely what you need to use.
Here is the sample from Parse:
PFQuery *query = [PFQuery queryWithClassName:#"Comment"];
// Retrieve the most recent ones
[query orderByDescending:#"createdAt"];
// Only retrieve the last ten
query.limit = 10;
// Include the post data with each comment
[query includeKey:#"post"];
[query findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error) {
// Comments now contains the last ten comments, and the "post" field
// has been populated. For example:
for (PFObject *comment in comments) {
// This does not require a network access.
PFObject *post = comment[#"post"];
NSLog(#"retrieved related post: %#", post);
}
}];
Your code looks right on so far. Then to retrieve your Activity class values, you can use:
PFQuery *activityQuery = [PFQuery queryWithClassName:#"Activity"];
// Set contraints here, example:
[activityQuery setLimit:100];
[query findObjectsInBackgroundWithBlock:^(NSArray *array, NSError *error) {
if (!error) {
// Success, do something with your objects.
}
}];

Parse query always true

Perhaps this is not the right place for this, but I am sure that many users here are familiar with Parse framework for iOS. Basically I am having issues with a query, all I want to do is check if a username already exists (they do so at login) except I need to do it in order to set up a relationship between the current user and another user. Currently my method is:
PFQuery *query = [PFUser query];
[query whereKey:#"username" equalTo:username.text];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"query returned with result");
for (PFObject *object in objects) {
NSLog(#"%#", object.objectId);
}
}
else {
NSLog(#"Nope");
}
}];
username is just a string containing the word entered in plain text from UITextField. But no matter what I put in, the query seems to go through and I get a message of success. I even tried iterating through the objects as shown in the for loop and I get nothing logged. What is going on here?
EDIT
Just for clarification, username is simply taken from a IBOutlet UITextField *username from the view controller which takes in the username from input. I have tested to make sure that it is being taken correctly. If I enter "foo", I can log the username.text and it will be "foo", however I have no registered users named "foo" so I do not understand why the query is returning without error.
You will get message of success even there is no object found.
(Try log objects.count)
If so, you should check your spelling on Key Value or Query Value.
They are case-sensitive.