I want to check if the currentUser is the same as the user that created the post in order to display a button that would let the user delete that post.
I figured the best way would be to match the currentUser.objectId with the Post's "user Pointer<_User>".
I'm logging the currentUser's objectId with this code:
PFUser *currentUser = [PFUser currentUser];
NSString *currentUserID = currentUser.objectId;
NSLog(#"%#", currentUserID);
How can I log the Post's user Pointer<_User>?
Thanks.
First thing to do is to query the desired post object and then you can get the user pointer like retrieving the common value:
PFObject *post = ...; // I assume you know how to get your desired object
PFUser *postedUser = post[#"user"]; // user is the column name
Related
The childByAutoId would be useful if you want to save in a node multiple children of the same type, that way each children will have its own unique identifier.
pet:{
KJHBJJHB:{
name:fluffy,
owner:John Smith,
},
KhBHJBJjJ:{
name:fluffy,
owner:Jane Foster,
}
}
Therefore, once I have that uID, and I want to retrieve an specific user using the his/her uID. How do I tell Firebase that I want that specific user? Because I create it and store it in Firebase, but then to read it, don't I need to know the value of the uID? Where do I get it from?
What function do I use to retrieve for example the second user using the uID?
Thanks in advance..
in the title u ask how to get rid so:: get the new ref's key property to get the aid created
FIRDatabaseReference *ref = parent.childByAutoID
NSString *uid = ref.key
BUT thats not what you want id say, so:
to filter out all children where owner = XY which you want I think:
FIRDatabaseReference *ref = your pets node
FIRDatabaseQuery *allPets = [ref queryOrderedByChild:#"owner"];
FIRDatabaseQuery *specificPet = [allPets queryEqualToValue:#"XY"];
[specificPet observeEventType:FEventTypeChildAdded withBlock:^(FIRDataSnapshot *snapshot) {
NSDictionary *dict = snapshot.value;
NSString *key = snapshot.key;
NSLog(#"key = %# for child %#", key, dict);
}];
see: Query users by name or email address using Firebase (Swift)
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.
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).
I want to retrieve the current users string value on a specific column from the user class in Parse.com
I have tried this code:
NSString *columnString = [[[PFUser currentUser] objectForKey:#"columnKey"] stringValue];
This code logged an error saying "unrecognized selector sent to instance.."
What is the correct way to do this?
If your column datatype is String then try below snippet.
NSString *str_ColumnString = [NSString stringWithFormat:#"%#",[[PFUser currentUser]valueForKey:#"columnKey"]];
My User class has a many-to-many relationship with the Convos class. I want to add user (which is a PFUser * that is not the current logged-in user) to convo object, and I want to add convo to the user object for the inverse relation.
PFRelation *relation = [self.convo relationforKey:#"users"];
[relation addObject:user];
[self.convo save];
PFRelation *inverseRelation = [user relationforKey:#"convos"];
[inverseRelation addObject:self.convo];
[user save];
The problem is that I am not allowed to save user because apparently I can only save the currently logged-in user. Here is the error:
User cannot be saved unless they have been authenticated via logIn or signUp
How do I get around this?
Easiest way I can think of would be to have a separate PFObject which owns the Convos relation. For e.g.
PFUser["proxy"] -> PFObject["convos"] -> PFRelation
Your code would then become:
PFObject *relation = [self.convo relationforKey:#"users"];
[relation addObject:user];
PFObject *userProxy = [user objectForKey:#"proxy"];
// N.B. You need to make sure this object exists already, and create it if not
// N.B. Make sure you include this key when you query for the user, or you'll need to load the data here
if (userProxy == nil) NSAssert(nil, #"Need to create the users Proxy object");
if (userProxy.isDataAvailable == NO) NSAssert(nil, #"Need to include the Proxy object key in the user query");
PFRelation *inverseRelation = [userProxy relationforKey:#"convos"];
[inverseRelation addObject:self.convo];
[PFObject saveObjects:#[self.convo, userProxy]];