raginggoat
raginggoat

Reputation: 3600

Save Data to Another User Object

I am trying to save the current users username to an an array associated with another user but the ACL doesn't allow writing data to another user object. The code lets you enter a username and if the user exists, it adds that username to an array of users you follow. When you start following a user, your username needs to be added to the followers array for the person you just followed. How can I do this?

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    if (buttonIndex == 1) {
        UITextField *alertTextField = [alertView textFieldAtIndex:0];
        self.username = alertTextField.text;

        PFQuery *query = [PFUser query];
        [query whereKey:@"username" equalTo:self.username];
        PFUser *user = (PFUser *)[query getFirstObject];

        NSLog(@"User: %@", user[@"username"]);

        if (!(user[@"username"] == NULL)) {
            if (![self.followersList containsObject:user[@"username"]]) {
                [self.followersList addObject:user[@"username"]];
                [[PFUser currentUser]setObject:self.followersList forKey:@"Following"];
                [[PFUser currentUser]saveInBackground];

                NSMutableArray *otherUsersFollowers;

                if ([user objectForKey:@"Followers"] == NULL) {
                    otherUsersFollowers = [[NSMutableArray alloc]init];
                }
                else {
                    otherUsersFollowers = [user objectForKey:@"Followers"];
                }

                [otherUsersFollowers addObject:[PFUser currentUser].username];
                [user setObject:otherUsersFollowers forKey:@"Followers"];
                [user saveInBackground];

                [self.tableView reloadData];
            }
            else {
                UIAlertView *alreadyFollow = [[UIAlertView alloc]initWithTitle:@"" message:@"You already follow that user." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                [alreadyFollow show];
            }
        }
        else {
            UIAlertView *noUserAlert = [[UIAlertView alloc]initWithTitle:@"" message:@"That user does not exist" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [noUserAlert show];
        }
    }
}

Upvotes: 0

Views: 63

Answers (2)

knshn
knshn

Reputation: 3461

You need to use cloud code with master key. The master key allows you to bypass class-level permissions and ACLs. In your iOS code call your cloud function:

NSDictionary *params = @{@"otherUserId": @(user.objectId), @"username": [PFUser currentUser].username};
[PFCloud callFunctionInBackground:@"addFollower" withParameters:params block:^(id object, NSError *error) {
    // Probably you want to reload your table here    
}];

The cloud function can be like:

function addFollower (request, response) {
    var user = request.user;
    var otherUserId = request.params.otherUserId;
    var username = request.params.username;
    if (!user) {
        response.error("Need to login");
        return;
    } else if (!otherUserId) {
        response.error("Need the other user's id");
        return;
    } else if (!username) {
        response.error("Need the current user's username");
        return;
    }

    var otherUser = Parse.User.createWithoutData(otherUserId);
    otherUser.addUnique("followers", username);
    otherUser.save(null, {useMasterKey:true}).then(function (otherUser) {
        response.success();
    }, function (error) {
        response.error(error);
    })
}

Parse.Cloud.define("addFollower", addFollower);

Notice that I use save with useMasterKey:true option so that the ACL will be bypassed in this particular save. Instead, you could also add a line of Parse.Cloud.useMasterKey(); in the beginning of this function, that would let you bypass ACLs in all operations within the function. More info in the docs.

You may also want to move the part that you update followings of the current user into this cloud code function.

Upvotes: 1

Wain
Wain

Reputation: 119041

Either don't and run a query to find all of the followers or do it in cloud code where you can use the master key.

Upvotes: 0

Related Questions