rihekopo
rihekopo

Reputation: 3350

Can't write non current user objects by PFUser currentuser

I would like write a PFUser object by the currentUser, i've added the ACL based on the Parse developer guide, but i still get an error:

 'User cannot be saved unless they have been authenticated via logIn or signUp'    

_ My code:

PFQuery *query = [PFUser query];
    [query whereKey:@"username" equalTo:self.bBo];
    PFObject *friendData = [query getFirstObject];

    PFUser *user = (PFUser *)friendData;

    PFACL *userACL = [PFACL ACL];

    user.ACL = userACL;

    [userACL setWriteAccess:YES forUser:[PFUser currentUser]];

    PFRelation *friendRelation = [user relationforKey:@"array"];
    [friendRelation addObject:[PFUser currentUser]];

    [user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (error){
            NSLog(@"Error %@ %@", error, [error userInfo]);
        }
    }];

I think i did everything correct, so i can't figure out what can be the problem. So if you made earlier something like this or know where is the problem, i would really appreciate any suggestions.

Upvotes: 2

Views: 2021

Answers (1)

user3344977
user3344977

Reputation: 3604

For security reasons, Parse won't allow you to save any changes to a user that is not currently logged in.

If you want to be able to make and save changes to user, you need to use Cloud Code and the Master Key to get around this roadblock.

I have had multiple problems like this before, and every time I've been forced to use a workaround via Cloud Code.

Here's an example of a workaround I did for creating a friends relationship between two users:

[PFCloud callFunction:@"editUser" withParameters:@{@"userId": user.objectId}];

The above code statement is in xcode, and executes the function I have added to my Cloud Code file.

Then, here's what my Cloud Code file looks like:

Parse.Cloud.define('editUser', function(request, response) {
    var userId = request.params.userId;

    var User = Parse.Object.extend('_User'),
        user = new User({ objectId: userId });

    var currentUser = request.user;

    var relation = user.relation("friendsRelation");
    relation.add(currentUser);

    Parse.Cloud.useMasterKey();
    user.save().then(function(user) {
        response.success(user);
    }, function(error) {
        response.error(error)
    });
});

The above code uses the Master Key to save changes to both the currently logged in user, and to the user who's objectId was passed into this function.

Code details:

var relation

This is just a variable I'm creating to hold what the following fucntion returns:

user.relation("friendsRelation");

In the above function, "friendsRelation" is the name of my PFRelation key in Parse.

Now that we have a valid relation object contain in our variable called relation, we execute this function with an argument of our currentUser object.

After that, all that's left is saving everything. I don't program with javascript, but I was still able to come up with the above solution by looking at the Parse Cloud Code docs, and searching around on their support forums.

If you take my template from above, and make some small changes, then you should be able to easily accomplish what you need. You just have to jump through these extra hoops because the Parse SDK doesn't want a situation where someone can login and somehow make changes to another user's account, whether by their own fault or a developer's mistake.

EDIT:

Here is the code to add the relationship for the current user:

PFRelation *friendsRelation = [[PFUser currentUser]relationforKey:@"friendsRelation"];

    PFUser *user = [self.parseUsers objectAtIndex:indexPath.row];

    [friendsRelation addObject:user];
    [currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (error) {
            NSLog(@"%@ %@", error, [error userInfo]);
        }
    }];

And then you can call the Cloud Code method right after:

    [PFCloud callFunction:@"editUser" withParameters:@{
                                                       @"userId": user.objectId
                                                       }];

Upvotes: 9

Related Questions