I am trying to add a list people who follow a user to the column titled "Followers" under the user, which is retrieved from objectatindex of a sender tag.
Here is the code:
-(void)followButton:(id)sender {
UIButton *senderButton = (UIButton *)sender;
NSLog(#"current Row=%ld",(long)senderButton.tag);
PFObject *object = [self.objects objectAtIndex:senderButton.tag];
if (![[object objectForKey:#"followers"]containsObject:[PFUser currentUser].objectId]) {
[[PFUser currentUser] addUniqueObject:object.objectId forKey:#"following"];
[[PFUser currentUser] saveInBackground];
PFUser *otherUser = [self.objects objectAtIndex:senderButton.tag];
NSLog(#"Followed %#", otherUser);
[otherUser addUniqueObject:[PFUser currentUser].objectId forKey:#"followers"];
[otherUser saveInBackground];
// NSLog(#"Followed %#", object);
} else {
[[PFUser currentUser] removeObject:object.objectId forKey:#"following"];
[[PFUser currentUser] saveInBackground];
PFUser *otherUser = [self.objects objectAtIndex:senderButton.tag];
[otherUser removeObject:[PFUser currentUser].objectId forKey:#"followers"];
[otherUser saveInBackground];
}
[self.tableView reloadData];
}
For some reason, the code above only adds to the array of "Following" of the current user. When re-clicked, the object is to be removed but nothing happens. Additionally, the code
PFUser *otherUser = [self.objects objectAtIndex:senderButton.tag];
[otherUser removeObject:[PFUser currentUser].objectId forKey:#"followers"];
[otherUser saveInBackground];
does absolutely nothing meanwhile it supposed to do the work of add to the "Followers" array of the user at the selected row. What am I doing wrong? The goal's to get a working following/followers action. I'm using PFQueryTableViewController!
You can't modify other user's objects from the client. You can only modify the current user. The way to modify users that are the current user is to use the master key in the cloud code by using Parse.Cloud.useMasterKey();
https://parse.com/questions/how-can-i-allow-a-user-to-edit-another-user
So create a function in the cloud code by passing the username of the "otherUser" and the objectId that you want to remove
Parse.Cloud.define("RemoveFollower", function(request, response){
var username = request.params.username;
var id_to_remove = request.params.objectId_passed;
var query = new Parse.Query(Parse.User);
query.equalTo("username", username);
query.find({
success: function(results){
var u = results[0];
//u modify the user u however you like...
u.save();
response.success("Success");
},
error: function(){
response.error("Error");
}
});
Related
This is using Parse btw.
I have information saved into the users class using this code here
-(IBAction)saveButtonAction:(id)sender {
PFUser *currentUserSave = [PFUser currentUser];
userBioString = userBio.text;
genderFieldString = genderField.text;
ageFieldString = ageField.text;
currentUserSave[#"userBioParse"] = userBioString;
currentUserSave[#"userGenderParse"] = genderFieldString;
currentUserSave[#"ageFieldParse"] = ageFieldString;
[[PFUser currentUser] saveInBackground];
[[PFUser currentUser] fetch];
Now I am trying to call back the information using a query. I researched how to do it and this is my result as of now.
-(IBAction) userProfileQuery {
NSString *bioQueryString = [[PFUser currentUser] objectForKey:#"userBioParse"];
userBio.text = bioQueryString;
NSString *ageQueryString = [[PFUser currentUser] objectForKey:#"ageFieldParse"];
ageField.text = ageQueryString;
NSString *genderQueryString = [[PFUser currentUser] objectForKey:#"genderFieldParse"];
genderField.text = genderQueryString;
the information is being saved into the users class successfully. I am just unsure how to retrieve it... Thanks in advance for any feedback!
There are more than one way to get the currentUsers information in parse. Try this code out. Its the most complicated one, but reading the code its easier to understand what you are doning.
PFQuery *query= [PFUser query];
[query whereKey:#"username" equalTo:[[PFUser currentUser]username]];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error){
if (!error) {
userBio.text = [object valueForKey:#"userBioParse"];
ageField.text = [object valueForKey:#"ageFieldParse"];
genderField.text = [object valueForKey:#"genderFieldParse"];
}
else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
If you are doing it the way you are doing it, try, thats a litte bit of a shortcut:
PFUser *user = [[PFUser currentUser];
userBio.text = user.userBioParse;
Parse already gives you most of the code for currentUser. And the fastest way to get currentUser information that parse offers is:
userBio.text = currentUser.userBioParse;
- (IBAction)savePasswordButton:(id)sender {
PFObject *myPassword = [PFObject objectWithClassName:#"_User"];
myPassword[#"password"] = self.myPasswordfield.text;
[myPassword saveInBackground];
}
The problem is here: For the _User class I can't see anything in the databrowser, but when I try with other classes it works successfully
Does anyone could explain me where am I wrong ?
According to Parse documentation, 'User' is a built-in class.
PFUser *user = [PFUser currentUser];
user.password = self.myPasswordfield.text;
[user saveInBackground];
I am trying to get my head around PFRelation in parse. I have a class called "girlBio" that stores information about girls and a class called "stuff" that stores information about items. code below:
PFObject *item = [PFObject objectWithClassName:#"stuff"];
item[#"Name"] = #"PS3";
PFObject *girl = [PFObject objectWithClassName:#"girlBio"];
girl[#"Name"] = #"Jessica";
PFObject *girl2 = [PFObject objectWithClassName:#"girlBio"];
girl2[#"Name"] = #"Cindy";
PFRelation *relation = [item relationForKey:#"owners"];
[relation addObject:girl];
[relation addObject:girl2];
[item saveInBackground];
--------------------------------- update also tried this -------------------------
PFObject *item = [PFObject objectWithClassName:#"stuff"];
item[#"Name"] = #"PS3";
PFObject *girl = [PFObject objectWithClassName:#"girlBio"];
girl[#"Name"] = #"Jessica";
[item saveInBackground];
[girl saveInBackground];
PFRelation *relation = [item relationForKey:#"owners"];
[relation addObject:girl];
[item saveInBackground];
So I want this item to be owned by several girls however when I run the program I get this error:
Error: can't add a non-pointer to a relation (Code: 111, Version: 1.6.0)
Can someone help please?
Thank you
You need to save your objects girl1 and girl2 before saving the relationship. Otherwise, even thought your local copy knows about them, the server does not.
UPDATE
You also need to make sure the saves for girl1 and girl2 and item complete before you save the relation. However, you probably don't want to run these saves on the primary thread, so I'd recommend something like this (which I just ran without issue):
dispatch_async(dispatch_get_main_queue(), ^{
PFObject *item = [PFObject objectWithClassName:#"stuff"];
item[#"Name"] = #"PS3";
PFObject *girl = [PFObject objectWithClassName:#"girlBio"];
girl[#"Name"] = #"Jessica";
[item save];
[girl save];
PFRelation *relation = [item relationForKey:#"owners"];
[relation addObject:girl];
[item saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
//Do something after the last save...
}];
});
I have a problem with incrementKey. I'd like to increment two keys of my user class, and they're not incrementing. Here's my code, if you want more details feel free to ask.
- (void) updateUserNbrQuestionsAnswered: (NSString*)FacebookID;
{
NSLog(#"%#", FacebookID);
PFQuery *queryUser = [PFQuery queryWithClassName:#"User"];
[queryUser whereKey:#"FacebookID" equalTo:FacebookID];
PFObject *user = [queryUser getFirstObject];
[user incrementKey:#"NbrQuestionsAnswered" byAmount:[NSNumber numberWithInt:1]];
[user incrementKey:#"Points" byAmount:[NSNumber numberWithInt:5]];
[user save];
};
I call this function every time the user hits a button, which reload the view after incrementing on parse and updating a label. Thanks in advance for your help !
Use this:
PFQuery *queryUser = [PFUser query]
Change the save method with
PFObject* user;
...
..
.
NSError* anyErr = NULL;
[user save:&anyErr];
Ensure you have the write permission to alter the values of the User table (see ACL)
i'm trying to post the users location with his display name in the Table View. but all I'm getting in the data browser is the correct post but the display name is blank
I'm trying to query the location Class and also the User Class which has the display name for the user
// Configure the new event with information from the location.
CLLocationCoordinate2D coordinate = [location coordinate];
PFGeoPoint *geoPoint = [PFGeoPoint geoPointWithLatitude:coordinate.latitude longitude:coordinate.longitude];
PFObject *object = [PFObject objectWithClassName:#"Location"];
[object setObject:geoPoint forKey:#"location"];
PFObject *UserObject = [PFObject objectWithClassName:#"_User"];
[[UserObject objectForKey:#"postedUser"] objectForKey:#"displayName"];
// Create relationship
[object setObject:[PFUser currentUser] forKey:#"postedUser"];
[UserObject setObject:[PFUser currentUser] forKey:#"displayName"];
PFACL *locatinACL = [PFACL ACLWithUser:[PFUser currentUser]];
[locatinACL setPublicReadAccess:YES];
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
}
}];
anyone know what I'm doing wrong. the display name is in the user class under displayName and i need it in the new post under displayName
the user save details saved under a form where the set has to fill in extra details after sign up
NSString *saveName = UserNameText.text;
NSString *saveEmail = EmailAddressText.text;
NSString *saveMobile = MobileText.text;
NSString *saveAdd1 = Address1Text.text;
NSString *saveAdd2 = Address2Text.text;
NSString *savePostCode = PostCodeText.text;
NSString *saveCustTax = TaxiOrCust.text;
currentUserSave[#"displayName"] = saveName;
currentUserSave[#"email"] = saveEmail;
currentUserSave[#"mobile"] = saveMobile;
currentUserSave[#"address1"] = saveAdd1;
currentUserSave[#"address2"] = saveAdd2;
currentUserSave[#"postCode"] = savePostCode;
currentUserSave[#"customer"] = saveCustTax;
Forgive the long answer... I think I'm still slightly unclear about your data structure and what you're trying to achieve, so it seems to make the most sense if I clarify what your existing code is actually doing. Hopefully this will help you make any necessary adjustments.
What you're currently doing
PFObject *object = [PFObject objectWithClassName:#"Location"];
[object setObject:geoPoint forKey:#"location"];
Here you're creating a new Location object, and setting the geopoint you've created as its location. If you have an existing Location object you want to update, you'll have to fetch that from Parse (unless you already have a variable / property for it).
PFObject *UserObject = [PFObject objectWithClassName:#"_User"];
Here you're creating a new User object. I suspect you want to use the current user, rather than create a new one, however. There's also a specific Parse object for users: PFUser - which you are using later on.
[[UserObject objectForKey:#"postedUser"] objectForKey:#"displayName"];
This line does nothing. You're fetching UserObject's postedUser property, and then fetching that user's displayName property. I don't think this is what you were intending.
[object setObject:[PFUser currentUser] forKey:#"postedUser"];
[UserObject setObject:[PFUser currentUser] forKey:#"displayName"];
This then updates the two new objects you created (your location and user objects), by setting two of their attributes to point to the current user.
PFACL *locatinACL = [PFACL ACLWithUser:[PFUser currentUser]];
[locatinACL setPublicReadAccess:YES];
These two lines create a new ACL which gives the current user write access, and everybody else read access. However, you're not applying this to your new location object.
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
}
}];
Finally, this will save your new Location object. However, the new User object you created will not be saved, as nothing else has a reference to it, and you're not calling save on it.
What you might be trying to do
I think the code you're writing can probably be cut down to something along these lines:
// Create a new location object
PFObject *parseLocation = [PFObject objectWithClassName:#"Location"];
// Create a new PFGeopoint, and store it as the location's location.
CLLocationCoordinate2D coordinate = [location coordinate];
PFGeoPoint *geoPoint = [PFGeoPoint geoPointWithLatitude:coordinate.latitude longitude:coordinate.longitude];
[parseLocation setObject:geoPoint forKey:#"location"];
// Store the current user and their display name as part of the location object
[parseLocation setObject:[PFUser currentUser] forKey:#"postedUser"];
[parseLocation setObject:[[PFUser currentUser] objectForKey:#"displayName"] forKey:#"displayName"];
// Create ACL and save it to the location object
PFACL *locationACL = [PFACL ACLWithUser:[PFUser currentUser]];
[locationACL setPublicReadAccess:YES];
[parseLocation setACL:locationACL];
// Save the location object
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
}
}];
Is this closer to what you wanted?