First i get the current user and the connected book to that user (It's a pointer to a book objectId). Then i want to find the book using the getobjectinBackgroundWithId method and then display the book name. When i change getObjectInBackgroundWithId:storeUserID to getObjectInBackgroundWithId:#"f4Dg92xC2" it works perfect!
PFUser *currentuser = [PFUser currentUser];
storeUserID = currentuser[#"connectedBook"]; //Store book id in a string
NSLog(#"%#", storeUserID); // what i get <Book:f4Dg92xC2:(null)>
PFQuery *query = [PFQuery queryWithClassName:#"Book"];
[query getObjectInBackgroundWithId:storeUserID block:^(PFObject *books, NSError *error){
PFObject *bookObject = books[#"bookName"];
NSLog(#"bookName:%#", bookObject);
}];
when i run this, the NSLog with the book name, shows:
Error: bad special key: objectId (Code: 102, Version: 1.2.20)
2014-09-17 23:28:56.529 MyApp[18977:90b] bookName:(null)
Thanks a lot in advance!!
Your comment //Store book id in a string is incorrect. A pointer doesn't return the string object id, it returns the object itself. So you already have it and you don't need to call getObjectInBackgroundWithId:.
The log <Book:f4Dg92xC2:(null)> even tells you it's a Book instance (not an NSString instance).
Related
So in my app I am using Parse for user accounts. I have a class "Follow" with "to" and "from" fields containing user object ids, allowing users to follow each other. Now, if I delete a user somehow, the follow relation remains in tact and querying empty user data raises an object not found error. What I want to know is how I can delete a follow relation if any of the "to" or "from" fields contains an objectID of an object that does not exist.
I have tried querying objects by their objectID, but any attempt at checking empty data (like checking if a user.username is nil) has resulted in a missing object error, and I can't check if an object is nil because Xcode says it never will be.
Thanks!
I think you need to acquire it manually, if you have deleted user, then you can delete all of its relations to maintain Database integrity, following is the code you would calling after deleting any User.
PFQuery * _to = [PFQuery queryWithClassName:#"Follow"];
[_to whereKey:#"to" equalTo:#"Replace UserID of Deleted User"];
PFQuery * _from = [PFQuery queryWithClassName:#"Follow"];
[_from whereKey:#"from" equalTo:#"Replace UserID of Deleted User"];
PFQuery *query = [PFQuery orQueryWithSubqueries:#[_to, _from]];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(#"Successfully retrieved %d relations.", results.count);
// Do something with the found objects, lets delete them all to intact relationship
[PFObject deleteAllInBackground:results];
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
Please follow this link for detailed description and information:
Parse Compound Queries
I have tried a PFQuer to fetch the list of messages which have the user in it :
PFQuery *query = [PFQuery queryWithClassName:#"Message"];
[query whereKey:#"idUser" equalTo:[PFUser currentUser]];
tmpMessages = [[NSMutableArray alloc] initWithArray:[query findObjects]];
however when I try to access to the user using the fetchInBackGroundWithBlock :
[user fetchInBackgroundWithBlock:^(PFObject * _Nullable object, NSError * _Nullable error) {
NSLog(#"user= %# ",[object valueForKey:#"username"]);
}];
I get this exception :
'NSInvalidArgumentException', reason: '-[PFRelation fetchIfNeededInBackgroundWithBlock:]: unrecognized selector sent to instance 0x7fa540d6d560'
I have also tried to incluse the user is the query using [query includeKey:#"idUser"] but I get the following exception : field idUser cannot be included because it is not a pointer to another object
When I show it using NSLog(#"user= %# ",object ); , I get
user= <PFRelation: 0x7fa3d85f63b0, 0x7fa3d85f5fd0.idUser -> _User>
What should I do to make it work ??
It looks like your user object is a PFRelation.
They are used to describe many to many relations in Parse.
It sounds like you have set this up possibly with the PFUser as the targetClass. You can access the objects using the query property of the relation.
The code would be like...
[relation.query findObjects...
Another solution is to change the backend on Parse so that the user property is actually a user object.
On Parse, when you enter the data browser...
If the user property looks like this...
the property is a PFRelation.
If the property looks like this...
the property is a Pointer to the PFUser object and so the user property will be a PFUser.
What does yours say? Relation<_User> or Pointer<_User>?
I am trying to implement functionality to store data about user's friends (request friend, received friend request, accepted request). I have two tables.
First table is _User with username column.
Second table is Friends. This table is keeping track of who are friends of the user. This table has two fields:
A pointer column to user table
An array column called receivedRequest. In this array I keep the _User's objectId who are send request to that user.
Table _User has one to one relation with Friends table but meanwhile there is an array field keeping information of user's friend. In this array I am saving objectId of other users. I am using an array to avoid repeating rows for each friend's request.
Fist I want to know if this is a good idea or there is any alternative better that this. Actually I have extra array columns which is recived requests. Send requests. And accepted requests. All of them are array.
Second I want to know how can I write a query to go to Friends table. Find current user row. Go to friendList column. Return name of each friends whose name is in that array?
Currently I am doing this:
- (PFQuery *)queryForTable {
//Query user's friend request
PFQuery *query = [PFQuery queryWithClassName:#"Friends"];
[query whereKey:#"user" equalTo:[PFUser currentUser]];
[query includeKey:#"receivedRequest"];
return query;
}
This is returning only Id of the use's added my current user. I need their name from _User table.
Here's what I'd do:
(1) the User class ought to be about the user's relationship with the app, a place for data that's just between the user and the app.
(2) For data that users want to share, have a Persona class that has an image, nickname, etc. Persona should contain a pointer to User and vice versa.
(3) Personae (Personas in common usage) make friend invitations and become friends.
(4) arrays of string object ids = bad, arrays of pointers = good. In fact, I can't think of a circumstance where I'd prefer a string object id over a pointer.
(5) A FriendInvitation ought to be its own object, where inviter and invitee are pointers to Persona.
(6) A friendship is a bilateral and symmetrical relationship (at least we always hope they are). A good representation for that might be a Friendship class that has an array of pointers to exactly two Persona objects.
Here are a few functions, given a data model:
Persona has a pointer to User, call it 'user', and User has a persona pointer. FriendInvitation has an inviter and invitee, both pointers to Persona. Friendship has an array of two pointers to Persona, call it friends
// get the current user's FriendInvitations
- (void)friendInvitationsWithCompletion:(void (^)(NSArray *, NSError *))completion {
PFObject *persona = [PFUser currentUser][#"persona"];
PFQuery *query = [PFQuery queryWithClassName:#"FriendInvitation"];
[query whereKey:#"invitee" equalTo:persona];
[query includeKey:#"inviter"];
[query findObjectsInBackgroundWithBlock:completion];
}
// get the current user's friendships
// remember, these are not the friends, but the objects that record pairings of friends.
// see the next function for the friends
- (void)friendshipsWithCompletion:(void (^)(NSArray *, NSError *))completion {
PFObject *persona = [PFUser currentUser][#"persona"];
PFQuery *query = [PFQuery queryWithClassName:#"Friendship"];
[query whereKey:#"friends" equalTo:persona];
[query includeKey:#"friends"];
[query findObjectsInBackgroundWithBlock:completion];
}
// get the current user's friends' personae
- (void)friendsWithCompletion:(void (^)(NSArray *, NSError *))completion {
PFObject *persona = [PFUser currentUser][#"persona"];
[self friendshipsWithCompletion:^(NSArray *friendships, NSError *error) {
if (!error) {
NSMutableArray *result = [#[] mutableCopy];
for (PFObject *friendship in friendships) {
NSArray *friends = friendship[#"friends"];
NSInteger indexOfFriend = ([friends indexOfObject:persona] == 0)? 1 : 0;
[result addObject:friends[indexOfFriend]];
}
completion(result, nil);
} else {
completion(nil, error);
}
}];
}
// agree to be friends with someone
- (void)becomeFriendsWith:(PFObject *)friend completion:(void (^)(BOOL, NSError *))completion {
PFObject *persona = [PFUser currentUser][#"persona"];
PFObject *friendship = [PFObject objectWithClassName:#"Friendship"];
friendship[#"friends"] = #[ persona, friend ];
[friendship saveInBackgroundWithBlock:completion];
}
// we could go on, but this should convey the basic ideas
Friends table should not have arrays, but single IDs (actually pointers). So for every incoming request or friendship, there should be a single, separate entry on the database. So your Friends object (or for a better name, Relationship, or Friendship, but that's my personal preference of course) should roughly have following properties:
first (_User)
second (_User)
type (String. Possible values: 'friends' or 'request', maybe even 'blocked')
And for every accepted request, make sure you are creating two entries, one with first=user1/second=user2 and one with first=user2/second=user1. While you could technically go without making double entries, it will just complicate things in the long run, making everything harder to maintain.
Im trying to retrieve the objectId of my parse records. I can save and retrieve data ok, but having gone through all parse documents, Google, and SO, I can't seem to get a clear answer on how to get the id for accessing records before the main block without hard coding the objectId as in the tutorial from Parse.
getObjectInBackgroundWithId:#"SS8Cw7rT1h" <-------- Trying to retrieve object id to go here
Im saving data to parse inc objectId here (all good)
PFObject *scheme = [PFObject objectWithClassName:#"SchemeProvider"];
//Sections of class
scheme[#"schemeName"] = self.schemeName.text;
scheme[#"schemeRegistrationNumber"] = self.registrationNumber.text;
//Save then get object id of saved row
[scheme saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
[scheme objectId];
NSLog(#"SCHEME ROW ID %#",[scheme objectId]);
}];
Retrieving from parse (all good) - except - can't get objectID before main block
PFQuery *queryScheme = [PFQuery queryWithClassName:#"SchemeProvider"];
//NSString *myobjectId = [queryScheme valueForKey:#"objectId"]; <------trying to retrive object id
[queryScheme getObjectInBackgroundWithId:#"SS8Cw7rT1h" block:^(PFObject *retrivedData, NSError *error) {
NSLog(#"All data = %#", retrivedData);
}];
I have just hit this problem and have an example for you in swift
There is a function that saves with a block in background
You can access the objectId while saving in the block thats run after saving it to the cloud
var foo = PFObject(className:"Foo")
foo["bar"] = "something"
foo.saveInBackgroundWithBlock(){(succeeded: Bool!, error:NSError!) in
if succeeded
{
self.fooLabel.text = foo.objectId
}
}
You could store the objectId for a certain object e.g in a data structure or with core data if you need it for later access
Otherwise you need to query the object with property values i guess
like seen here: https://www.parse.com/docs/ios_guide#queries-basic/iOS
Hope this helps
i'm using Parse.com I wanted to ask you something if you can ... How do I delete from the list the total number of users CurrentUser? I would avoid that the report will also be made with oneself: D Thank you all
Perfect Guys .. then I found the method ... In layman's terms to exclude the PFUser Current User from a query to show only the App users but not the CurrentUser is just the use of notEqualTo in the query but it should be associated with the string that we want to remove from the query
I hope this can help other people :)
Do not pay too much attention to the constants: D
PFQuery * query = [self.RelazioniUtenti query];
[query whereKey: FF_USER_NOMECOGNOME notEqualTo: [[PFUser currentUser] objectForKey: FF_USER_NOMECOGNOME]];
[query orderByAscending: FF_USER_NOMECOGNOME];
[query findObjectsInBackgroundWithBlock: ^ (NSArray * objects, NSError * error) {