2

While utilizing the Parse service, I'm trying to allow users to skip sign-in fields by logging into the app via Facebook and using the Facebook information to fill in fields. I'm using Parse's Cloud Code to make the swift client-side code as simple as possible. However, I'm getting a little talk-back from Parse.Cloud when trying to use the cloud code to set the Username and Email Address fields of Parse.User. I get the following errors when running it in-app.

[Error]: Can't modify username in the before save trigger (Code: 141, Version: 1.6.1)

And when removing the username function, I receive:

[Error]: Can't modify email in the before save trigger (Code: 141, Version: 1.6.1)

Through the same code, I'm also setting firstName and lastName without any errors using the same method. Below is the code used.

[CLOUD CODE]

function pad(num, size){ return ('000000000' + num).substr(-size); }

Parse.Cloud.beforeSave(Parse.User, function (request, response) {
    var token = request.object.get("authData").facebook.access_token
    Parse.Cloud.httpRequest({
        url: 'https://graph.facebook.com/v2.1/me?fields=first_name,last_name,email&access_token=' + token,
        success: function(httpResponse) {
             var responseData = httpResponse.data;

             request.object.set("email", responseData.email) // <- Error Occurs Here
             request.object.set("username", responseData.email.split("@")[0].concat(".", pad(Math.floor(Math.random()*10000),4))) // <- Error Occurs Here
             request.object.set("firstName", responseData.first_name)
             request.object.set("lastName", responseData.last_name)

             response.success()
        },
        error: function(){
            response.error("Something went wrong.")
        }
    })
})

[SWIFT CODE]

@IBAction func loginWithFacebookButtonAction(sender: AnyObject){
    loginWithFacebookButtonOutlet.setTitle("Logging In...", forState: UIControlState.Normal)
    let permissions = ["public_profile", "user_friends", "email"]
    PFFacebookUtils.logInWithPermissions(permissions, {
        (user: PFUser!, error: NSError!) -> Void in
        if user == nil {
            println("Uh oh. The user cancelled the Facebook login.")
        } else if user.isNew {
            println("User signed up and logged in through Facebook!")
            self.performSegueWithIdentifier("facebookToApp", sender: self)
        } else {
            println("User logged in through Facebook!")
            self.performSegueWithIdentifier("facebookToApp", sender: self)
        }
    })
}

Other questions here that I've encountered are caused when the user tries to use .save() instead of response.success() which doesn't seem to be the problem in this situation.

Many thanks.

schrismartin
  • 460
  • 4
  • 17
  • 1
    I have the same problem, did you get it solved? – Mahmoud Adam Mar 03 '15 at 09:02
  • 1
    I've dropped the problem and assumed that it's a hard-coded precaution Parse uses in order to assure the integrity of the input. – schrismartin Mar 19 '15 at 20:52
  • @ChrisMartin By dropping the problem, did you mean you just didn't manage to solve it? If you worked around it how did you do so? – fatuhoku Jan 13 '16 at 12:05
  • As @MahmoudAdam answered, username and email fields must be unique, as it seems that's how the User table on the database is keyed. Giving the user access to these fields could potentially offset the integrity of the tables. I ended up saving twice, at the cost of an api request. – schrismartin Jan 27 '16 at 15:25

1 Answers1

2

it seems that username & email can not be altered in beforeSave trigger as they should be unique

Right now, the email field cannot be modified on a beforeSave because this field should be unique. If you were to use a value that another user is already using, this would result in an error that your beforeSave method would not be able to handle.

reference: https://www.parse.com/questions/why-cant-i-modify-the-email-field-in-a-before-save-trigger

Mahmoud Adam
  • 5,772
  • 5
  • 41
  • 62
  • Then what is the best way of retrieving the Facebook e-mail and name of a user at sign up / login? The only way I can see at the moment is to perform this operation from the client side whenever a user logs in. i.e. do it in a Cloud Code Function / Job vs. `beforeSave` / `afterSave` hooks to evade the error. – fatuhoku Jan 13 '16 at 12:08
  • I found that the `email` field can't even be modified programmatically (i.e. running a script from a Node environment using the Parse JS SDK. Really frustrating, actually! – fatuhoku Jan 27 '16 at 21:29