parse-server
parse-server copied to clipboard
Error 206 cannot modify user for new Facebook user
Hello
I am getting error 206 after new Facebook user is saved and reason seems to be nil sessionToken. I am facing this for Apple sign in also randomly. This is probably getting fixed by https://github.com/parse-community/parse-server/pull/6416. Don't know whether Facebook issue will also be fixed.
I have one old account created on Heroku Parse server which works fine ie i am able to save attributes after login.
I was running server v3.9.0. tried upgrading till 4.0.2 but still failing.
I am updating PFUser object post login locally in iOS client using Swift. Not using cloud code for this.
Also failing on back4app v3.9.0. Sign in with Apple also failing on back4app but works randomly.
Works on local setup consistently. Local server installed using bootstrap.sh script.
I have seen some issued dated 2016 fixing this error but server code seems to have changed lot so cannot view the same code referred in https://github.com/parse-community/parse-server/pull/952
using FBSDKCoreKit 5.15.1, FBSDKLoginKit 5.15.1
Steps to reproduce
on iOS, Try login using a facebook account that is not yet created on Parse. Running iOS 13.3.1
Expected Results
After successful login, should be able to save other attributes in PFUser.current() object
Actual Outcome
The login is successful but saving any attributes fails with error 206 "cannot modify user xxxxx" Fails on back4app also. v3.9.0 Both Apple and Facebook new user registration and update work fine in local environment.
Environment Setup
-
Server
- parse-server version (Be specific! Don't say 'latest'.) : 3.9.0 to 4.0.2 (Local 3.10.0)
- Operating System: heroku-18 (Local MacOS 10.15.3)
- Hardware: heroku-18 (Local MacOS 10.15.3)
- Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): Both as mentioned above
-
Database
- MongoDB version: mLab 3.6.12 (Local 4.2.3)
- Storage engine: mLab
- Hardware: mLab
- Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): both
Logs/Trace
Mar 15 02:51:40 yovl app/web.1 error: Parse error: Cannot modify user kc30Xbk1wA. {"code":206,"stack":"Error: Cannot modify user kc30Xbk1wA.\n at RestWrite.runDatabaseOperation (/app/node_modules/parse-server/lib/RestWrite.js:1170:11)\n at /app/node_modules/parse-server/lib/RestWrite.js:127:17\n at processTicksAndRejections (internal/process/task_queues.js:97:5)"}
package.json used for deployment to Heroku
{
"name": "parse-server-example",
"version": "1.4.0",
"description": "Based on example Parse API server using the parse-server module",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/ashish-naik/parse-server.git"
},
"license": "MIT",
"dependencies": {
"express": "4.17.1",
"parse-server": "4.1.0",
"underscore":"*",
"parse": "2.11.0"
},
"scripts": {
"start": "node index.js"
},
"engines": {
"node": ">= 8",
"npm": ">= 5.7.1"
}
}
auth section in index.js
auth: {
facebook: {
appIds: process.env.FACEBOOK_APP_ID
},
apple: {
client_id: process.env.IOS_BUNDLE_ID
}
},
I'm having a similar issue too - perhaps related: If I login with Facebook successfully, then logout and try Sign-in with Apple using the same email associated with Facebook, I get a 500 returned - internal server error.
@henrytkirk Can you open a new issue and fill out the template. Any logs or sample code would help.
@ashish-naik Can you try facebook login on the backend with masterKey: true?
I am not using cloud code for login. Call from swift code.
I wanted you to try it and see if that would fix this
If login is successful does your current user have a sessionToken? To change a user you need to have permission to do so.
I will try. May take some time due to workplace priorities.
Yes sessionToken is nil after successful login.
@dplewis I tried below. Not good with cloud code so hope code is not wrong.
Cloud function
Parse.Cloud.define("loginWithFacebook", function(request) {
var params = request.params
var authData = params.authData
var id = params.id
var expiredBy = params.expiredBy
var facebookAuthData = {
"id": id,
"access_token": authData,
"expiration_date": expiredBy
}
Parse.FacebookUtils.logIn(facebookAuthData, { useMasterKey: true })
.then(function(user) {
if (user.isNew()) {
console.log("NEW User logged in with id " + user.id + " with session token : " + user.sessionToken)
} else {
console.log("Existing User logged in with id " + user.id + " with session token : " + user.sessionToken)
}
})
.catch(function(error) {
console.log('ERROR','loginWithFacebook() - Error with facebook login : '+ error);
throw error
})
})
ios Code
func processFBLogin() {
if let accessToken = AccessToken.current {
logger.debug("Facebook user logged in with toke \(accessToken.appID)- \(accessToken.tokenString)")
PFCloud.callFunction(inBackground: "loginWithFacebook", withParameters: ["id":accessToken.userID, "authData":accessToken.tokenString, "expiredBy":accessToken.expirationDate], block: {
(response: Any?, error: Error?) -> Void in
if error == nil {
if let loggedinUser = PFUser.current() {
logger.debug("FB login successful - sessiontoken \(loggedinUser.sessionToken) ")
} else {
logger.debug("FB login failed ")
}
} else {
logger.error("Error with facebook login \(String(describing: error?.localizedDescription))")
}
})
} else {
logger.info("No FB token available")
}
}
Server log
info: Ran cloud function loginWithFacebook for user undefined with:
Input: {"id":"xxxxxxxxxx","expiredBy":"2020-05-24T15:48:42.018Z","authData":"adasdasdasdasdasdasda"}
Result: undefined {"functionName":"loginWithFacebook","params":{"id":"xxxxxxxxxx","expiredBy":"2020-05-24T15:48:42.018Z","authData":"adasdasdasdasdasdasda"}}
verbose: RESPONSE from [POST] /parse/functions/loginWithFacebook: {
"response": {}
} {"result":{"response":{}}}
verbose: REQUEST for [POST] /parse/users: {
"authData": {
"facebook": {
"id": "xxxxxxxxxx",
"access_token": "adasdasdasdasdasdasda",
"expiration_date": {
"__type": "Date",
"iso": "2020-05-24T15:48:42.018Z"
}
}
}
} {"method":"POST","url":"/parse/users","headers":{"host":"myApp.herokuapp.com","connection":"close","user-agent":"node-XMLHttpRequest, Parse/js2.11.0 (NodeJS 13.11.0)","accept":"*/*","content-type":"text/plain","x-request-id":"c9ec003f-70c6-4b03-bb2e-acbda997836b","x-forwarded-for":"54.92.152.225","x-forwarded-proto":"https","x-forwarded-port":"443","via":"1.1 vegur","connect-time":"1","x-request-start":"1585152709435","total-route-time":"0","content-length":"569"},"body":{"authData":{"facebook":{"id":"xxxxxx","access_token":"adasdasdasdasdasdasda","expiration_date":{"__type":"Date","iso":"2020-05-24T15:48:42.018Z"}}}}}
heroku/router at=info method=POST path="/parse/functions/loginWithFacebook" host=myApp.herokuapp.com request_id=2d5de5a0-f465-4387-aa7a-e4c3f575566c fwd="122.169.14.163" dyno=web.1 connect=1ms service=14ms status=200 bytes=625 protocol=https
heroku/router at=info method=POST path="/parse/users" host=myApp.herokuapp.com request_id=c9ec003f-70c6-4b03-bb2e-acbda997836b fwd="54.92.152.225" dyno=web.1 connect=1ms service=298ms status=201 bytes=794 protocol=https
verbose: RESPONSE from [POST] /parse/users: {
"status": 201,
"response": {
"objectId": "efsyICJCAq",
"createdAt": "2020-03-25T16:11:49.440Z",
"username": "hDTtBCA6oSpZGDR7a9kpemoFC"
},
"location": "http://myApp.herokuapp.com/parse/users/efsyICJCAq"
} {"result":{"status":201,"response":{"objectId":"efsyICJCAq","createdAt":"2020-03-25T16:11:49.440Z","username":"sdfsdfsdfsdf"},"location":"http://myApp.herokuapp.com/parse/users/efsyICJCAq"}}
Existing User logged in with id efsyICJCAq with session token : undefined
if i run code for a registered user without master key, i get sessionToken printed in logs.
But i am getting undefined for sessionToken for user.sessionToken or user.getsessionToken. Not sure to fetch access token.
Moreover, in Xcode i get PFUser.current as nil.
Does above help?
@dplewis Did you get a chance to look at my code?
Hope you are safe and doing well in this difficult times.
I can look into it, can you open a similar post in the iOS SDK?
Created https://github.com/parse-community/Parse-SDK-iOS-OSX/issues/1492
@dplewis I had opened 1477 post awhile back for Sign in with Apple. The symptoms are same as Facebook login issue that i created for you to look at. I have added some details of investigation there but realized it is marked closed. Can you please have a look? Should i remove the details from there and repost here?
@dplewis did you get a chance to check? Although you asked me to open this issue in iOS SDK repo (which i did, linked above), i think this has to do with server.
I am stuck at this since many days. Really appreciate if you could take a look.
Today i tested on local server on my Mac with same config as Heroku ie npm v 6.13.7 node v 9.4.0 parse server 4.2.0
it worked on local but didnt on Heroku. I noticed that this.storage['authprovider'] is undefined in createSessionTokenIfNeeded to createSessionToken() isnt called.
RestWrite.prototype.createSessionTokenIfNeeded = function() {
logger.info('Message - createSessionTokenIfNeeded - For class - ' + this.className)
if (this.className !== '_User') {
return;
}
// Don't generate session for updating user (this.query is set) unless authData exists
if (this.query && !this.data.authData) {
return;
}
logger.info('Message - createSessionTokenIfNeeded - Not update call - going ahead')
// Don't generate new sessionToken if linking via sessionToken
if (this.auth.user && this.data.authData) {
return;
}
logger.info('Message - createSessionTokenIfNeeded - not linking so going ahead')
if (
!this.storage['authProvider'] && // signup call, with (THIS IS FAILING)
this.config.preventLoginWithUnverifiedEmail && // no login without verification
this.config.verifyUserEmails
) {
// verification is on
logger.info('Message - createSessionTokenIfNeeded - returning as no auth provider, preventLoginWihoutEmail, verifyEmail')
logger.info('Message - createSessionTokenIfNeeded - authProvider = ' + this.storage['authProvider'] + ' preventLoginWihoutEmail = ' + this.config.preventLoginWithUnverifiedEmail + ' verifyUserEmails = ' + this.config.verifyUserEmails)
return; // do not create the session token in that case!
}
logger.info('Message - createSessionTokenIfNeeded - before calling - return this.createSessionToken()' )
return this.createSessionToken();
};
Some more logs from RestWrite.js from Heroku.
I noticed that validateAuthData is called twice. First time findUsersWithAuthData finds nothing and sign up fails. Second time findUsersWithAuthData find row but createSessionTokenIfNeeded() isnt called.
Message - before return this.getUserAndRoleACL() Message - before return this.validateClientClassCreation() Message - before return this.handleInstallation() Message - before return this.handleSession() Message - before return this.validateAuthData() Message - validateAuthData - is a _User class with valid username Message - validateAuthData - auth method supported. Going ahead MESSAGE - validateAuthData - provider = apple Message - validateAuthData - Abt to call handleAuthData with auData [object Object] MESSAGE - findUsersWithAuthData - providers length 1providers - apple MESSAGE - findUsersWithAuthData - queryKey authData.apple.id MESSAGE - findUsersWithAuthData - authData[provider].id xyz MESSAGE - findUsersWithAuthData - query.length 1 MESSAGE - findUsersWithAuthData - findPromise length undefined MESSAGE - findUsersWithAuthData - before return findPromise MESSAGE - handleAuthData - Results count is 0 Message - before return this.runBeforeSaveTrigger() Message - before return this.deleteEmailResetTokenIfNeeded() Message - before return this.validateSchema() Message - before return this.setRequiredFieldsIfNeeded() Message - before return this.transformUser() Message - before return this.expandFilesForExistingObjects() Message - before return this.destroyDuplicatedSessions() Message - before return this.runDatabaseOperation() Message - before return this.createSessionTokenIfNeeded() Message - createSessionTokenIfNeeded - For class - _User Message - createSessionTokenIfNeeded - Not update call - going ahead for _User Message - createSessionTokenIfNeeded - not linking so going ahead for _User Message - createSessionTokenIfNeeded - returning as no auth provider, preventLoginWihoutEmail, verifyEmail for _User Message - createSessionTokenIfNeeded - authProvider = undefined preventLoginWihoutEmail = true verifyUserEmails = true for _User Message - before return this.handleFollowup() Message - before return this.runAfterSaveTrigger() Message - before return this.cleanUserAuthData() Message - before return this.response() Message - before return this.getUserAndRoleACL() Message - before return this.validateClientClassCreation() Message - before return this.handleInstallation() Message - before return this.handleSession() Message - before return this.validateAuthData() Message - validateAuthData - is a _User class with valid username Message - validateAuthData - auth method supported. Going ahead MESSAGE - validateAuthData - provider = apple Message - validateAuthData - Abt to call handleAuthData with auData [object Object] MESSAGE - findUsersWithAuthData - providers length 1providers - apple MESSAGE - findUsersWithAuthData - queryKey authData.apple.id MESSAGE - findUsersWithAuthData - authData[provider].id xyz MESSAGE - findUsersWithAuthData - query.length 1 MESSAGE - findUsersWithAuthData - findPromise length undefined MESSAGE - findUsersWithAuthData - before return findPromise MESSAGE - handleAuthData - Results count is 1 MESSAGE - handleAuthData - storage authProvider = apple Message - before return this.runBeforeSaveTrigger() Message - before return this.deleteEmailResetTokenIfNeeded() Message - before return this.validateSchema() Message - before return this.setRequiredFieldsIfNeeded() Message - before return this.transformUser() Message - before return this.expandFilesForExistingObjects() Message - before return this.destroyDuplicatedSessions() Message - before return this.runDatabaseOperation()
@dplewis
I had opened a post in under iOS but seems the issue was at server side. I have tried to explain the probable cause and fix below.
When findUsersWithAuthData returns no result which means this user had not signed up earlier, below handleAuthDataValidation block handles auth validation and returns success since it is a valid auth.
return this.handleAuthDataValidation(authData).then(() => {
if (results.length > 1) {
// More than 1 user with the passed id's
throw new Parse.Error(
Parse.Error.ACCOUNT_ALREADY_LINKED,
'this auth is already used'
);
}
});
But in this flow, this.storage['authProvider'] is not set so below if statement in createSessionTokenIfNeeded evaluates to true and returns without calling this.createSessionToken().
if (
!this.storage['authProvider'] && // signup call, with
this.config.preventLoginWithUnverifiedEmail && // no login without verification
this.config.verifyUserEmails
) {
// verification is on
return; // do not create the session token in that case!
}
return this.createSessionToken();
So i tried this fix Move this line
this.storage['authProvider'] = Object.keys(authData).join(',');
from inside
if (results.length == 1) {
to just before it. and then set verifyUserEmails back to true. (This was suggested to be turned off by Nathan)
After this change sign up with facebook and login both worked, sign up and login with email also worked. I have not added function for linkWith in my app so cannot test it yet.
is this is a valid solution?
I tried to request you to check on iOS post but didnt get response hence raising again.
-Ashish
Hello
Can someone check this please?
@mtrezza when is this bug likely to be prioritized?
This thread has quite a potpourri of information.
I suggest to simplify and restate the issue as a comment, using the issue template, including:
- Verifying that the issue still exists with the latest version of Parse Server and the FB SDK.
- A step-by-step description (in list form) to replicate the issue, including the related code used in Parse Server Cloud Code and/or iOS.
I am also reclassifying this issue as "needs more info" until we can confirm that this is actually a bug.
@mtrezza i tested on local as well as Heroku with v4.4.0 and found Facebook login with new user is still failing.
Issue Login with new Facebook user fails with error code 206 Login with existing user works.
Steps to reproduce
- Install Parse server using package.json mentioned below.
- Use index.js mentioned below.
- Use new user to login for the first time. (i tried with test user)
Log Optional<NSError>
- some : Error Domain=Parse Code=206 "Cannot modify user o7GT48TZZT." UserInfo={code=206, temporary=0, error=Cannot modify user o7GT48TZZT., NSLocalizedDescription=Cannot modify user o7GT48TZZT.}
I cannot provide Parse Server log because somehow i am not able to enable even after setting VERBOSE=1 in heroku config vars. (this is another issue i can't solve)
Environment Setup
Server
parse-server version (Be specific! Don't say 'latest'.) : 3.9.0 to 4.4.0 (Local 4.4.0) Operating System: heroku-18 (Local MacOS 11.0.1) Hardware: heroku-18 (Local MacOS 11.0.1) Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): Both as mentioned above
Database
MongoDB version: MongoDb Atlas Sandbox cluster 4.2.10 (Local 4.2.3) Storage engine: mongoDB Atlas Hardware: MongoDB Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): both
Parse iOS SDK 1.91.1 FBSDKCoreKit 6.0.0
I don't login using cloud code so below is iOS code.
iOS Code snippet for Facebook login
PFFacebookUtils.logInInBackground(withReadPermissions: facebookPermissions) {
(loggedInUser: PFUser?, error: Error?) in
if error == nil && loggedInUser != nil {
//fetch email, name etc details from Facebook
saveUserDetailsOnParse(...)
}
func saveUserDetailsOnParse(isNewUser: Bool, user: PFUser?, socialId: String, email: String, name: String, profileImageURL: String?, loginProvider: String, callback: @escaping (String, NSError?) -> ()) {
if name != "" {
//if email based user logged in then name will be blank so update/add only if not blank ie for social login
PFUser.current()?["name"] = name
}
if profileImageURL != nil {
//if email based or Apple user logged in then URL will be blank so update/add only if not blank ie for social login
PFUser.current()?["profile_image_url"] = profileImageURL!
}
PFUser.current()?["email"] = email
if isNewUser {
//if logged in user isNew property is true
self.saveNewUserToParse(socialId: socialId, loginProvider: loginProvider) { (errorMessage, error) in
callback(errorMessage, error)
}
} else {
//save details for existing user
PFUser.current()?.saveInBackground(block: { (successSaveUser, error) in
if successSaveUser {
logger.debug("User attributes updated to Parse")
callback("User attributes updated to Parse", nil)
} else {
logger.debug("Error saving current PFUser post login to parse")
callback("Error saving current PFUser post login to parse", error! as NSError)
}
})
}
}
index.js
var express = require('express');
var cors = require('cors');
var ParseServer = require('parse-server').ParseServer;
var path = require('path');
var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;
var api = new ParseServer({
databaseURI: databaseUri,
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID,
masterKey: process.env.MASTER_KEY, //Add your master key here. Keep it secret!
serverURL: process.env.SERVER_URL , // Don't forget to change to https if needed
javascriptKey: process.env.JAVASCRIPT_KEY,// || '', //** add this line no need to set values, they will be overwritten by heroku config vars
restAPIKey: process.env.REST_API_KEY,// || '', //** add this line
clientKey: process.env.CLIENT_KEY,// || '', //** add this line
verbose:process.env.VERBOSE,
logLevel: process.env.LOG_LEVEL, // VERBOSE, INFO, ERROR, NONE, defaults to INFO
push: {
ios: {
pfx: 'certs/ApplePush.p12', // the path and filename to the .p12 file you exported earlier.
passphrase: process.env.APPLE_PUSH_PASSPHRASE,
topic: process.env.APPLE_PUSH_TOPIC, // The bundle identifier associated with your app
production: false //
}
},
auth: {
facebook: {
appIds: process.env.FACEBOOK_APP_ID
},
apple: {
client_id: process.env.IOS_BUNDLE_ID // optional (for extra validation), use the Service ID from Apple.
}
},
verifyUserEmails: true,
emailVerifyTokenValidityDuration: 2 * 60 * 60,
preventLoginWithUnverifiedEmail: true,
publicServerURL: process.env.SERVER_URL,
appName: process.env.APP_NAME,
emailAdapter: {
module: '@parse/simple-mailgun-adapter',
options: {
fromAddress: process.env.APP_SUPPORT_EMAIL,
domain: process.env.MAILGUN_DOMAIN,
apiKey: process.env.MAILGUN_API_KEY,
}
},
passwordPolicy: {
validatorPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/,
validationError: 'Password must have at least 8 characters, contain at least 1 digit, 1 upper case and 1 lower case character.',
doNotAllowUsername: true,
maxPasswordAge: 90,
maxPasswordHistory: 5,
resetTokenValidityDuration: 24*60*60,
}
});
var app = express();
app.use(cors());
// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);
// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
res.status(200).send('Make sure to star the parse-server repo on GitHub!');
});
// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function(req, res) {
res.sendFile(path.join(__dirname, '/public/test.html'));
});
var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
console.log('parse-server-example running on port ' + port + '.');
});
package.json
{
"name": "name",
"version": "1.0.0",
"description": " example Parse API server using the parse-server module",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/myrepo/my-parse-server"
},
"license": "MIT",
"dependencies": {
"express": "4.17.1",
"underscore":"*",
"parse": "2.12.0",
"cryptoutils":"*",
"cors":"*",
"parse-server": "4.4.0 "
},
"scripts": {
"start": "node index.js"
},
"engines": {
"node": ">9.0.0",
"npm": "6.13.7"
}
}
The code change i have tried and that works is in above comments. Also uploaded here ReadWrite.js
Thanks Ashish
Thanks for the details.
Can you please reduce the iOS code to a minimum example by removing all code that is not necessary to reproduce the issue?
The actual code path is not clear, there is also a function saveNewUserToParse
which is not posted here.
Then, in that minimum example, at which step in the iOS code does the server log 206 "Cannot modify user o7GT48TZZT."
?
sorry forgot that method where error occurs actually.
func saveNewUserToParse(socialId: String?, loginProvider: String?, callback: @escaping (String, NSError?) -> ()) {
// Setup some seed values for the newly created user
PFUser.current()?.saveInBackground(block: { (successSaveUser, error) in
//MARK: Getting error 206 here
if successSaveUser {
callback("New user's attributes saved to Parse", nil)
} else {
logger.debug("Error saving current PFUser post login/signup to parse \(error!.localizedDescription)")
callback("Error saving current PFUser post login/signup to parse", error! as NSError)
}
})
}
Can you please reduce the iOS code to a minimum example by removing all code that is not necessary to reproduce the issue?
I haven't tested this but removed all non-essential part.
import Parse
func loginWithFacebook() {
PFFacebookUtils.logInInBackground(withReadPermissions: facebookPermissions) {
(loggedInUser: PFUser?, error: Error?) in
if error == nil && loggedInUser != nil {
saveUserDetailsOnParse(isNewUser: loggedInUser!.isNew, user: loggedInUser! ,socialId: socialId, email: userEmail, name: userName, profileImageURL: profileImageURL, loginProvider: "facebook", callback: { (message, error) in
if error == nil {
//proceed to home screen
} else {
//show error
}
})
}
}
}
func saveUserDetailsOnParse(isNewUser: Bool, user: PFUser?, socialId: String, email: String, name: String, loginProvider: String, callback: @escaping (String, NSError?) -> ()) {
if name != "" && PFUser.current()?["name"] == nil {
PFUser.current()?["name"] = name
}
PFUser.current()?["email"] = email
if isNewUser {
//if logged in user isNew property is true
self.saveNewUserToParse() { (errorMessage, error) in
callback(errorMessage, error)
}
} else {
//save details for existing user
PFUser.current()?.saveInBackground(block: { (successSaveUser, error) in
if successSaveUser {
logger.debug("User attributes updated to Parse")
callback("User attributes updated to Parse", nil)
} else {
logger.debug("Error saving current PFUser post login to parse")
callback("Error saving current PFUser post login to parse", error! as NSError)
}
})
}
}
func saveNewUserToParse(callback: @escaping (String, NSError?) -> ()) {
//Set some initial values in PFUser.current()
PFUser.current()?.saveInBackground(block: { (successSaveUser, error) in
//MARK: Getting error 206 here
if successSaveUser {
callback("New user's attributes saved to Parse", nil)
} else {
logger.debug("Error saving current PFUser post login/signup to parse \(error!.localizedDescription)")
callback("Error saving current PFUser post login/signup to parse", error! as NSError)
}
})
}
could you please try to pass down the loggedInUser
var and save it instead of PFUser.current()? I'm wondering that at that point the PFUser.current() was not yet updated by the PFFacebookUtils. Anyways I believe this is an issue with the iOS SDK and not Parse Server.
tried saving loggedInUser but still failed with error 206.
I had raised in iOS SDK 1492
Can you tell me why my verbose setting doesn't work?
Would you be able to share the code that you tried saving loggedInUser?
Can you tell me why my verbose setting doesn't work?
Could you please open another issue with the details of that?
I add some seed values to newly created user. i added those to the code below.
func saveNewUserToParse(for newUser: PFUser, socialId: String?, loginProvider: String?, callback: @escaping (String, NSError?) -> ()) {
newUser["social_id"] = socialId
newUser["login_provider"] = loginProvider
// Setup seed values for the newly created user
newUser["amnt_earned"] = NSDecimalNumber.zero
newUser["amnt_paid"] = NSDecimalNumber.zero
newUser["items_bought"] = 0
newUser["items_sold"] = 0
newUser["max_items_allowed"] = 0
newUser["no_of_items"] = 0
newUser["read_only_mode"] = true
newUser["current_month_transaction_count"] = 0
newUser["isBanned"] = false
newUser.saveInBackground(block: { (successSaveUser, error) in
if successSaveUser {
logger.debug("User attributes updated to Parse")
} else {
callback("User already registered using the email address", error! as NSError)
}
})
}
i guess this is server issue. I have tried fixing the code and it works.
Pls read the issue i had created 1492 specifically from https://github.com/parse-community/Parse-SDK-iOS-OSX/issues/1492#issuecomment-614468661 onward.
have also explained the same above.
Thanks for providing all the details so far, but we are going in circles here.
Can you please
- reduce the iOS code to a minimum example by
- removing all code that is not necessary to reproduce the issue and
- providing the complete code.
This means, removing the 3 methods and fields that you are setting on the current user. Cut everything away until you get to maybe 3 or 4 lines of code, which should be enough to demonstrate the issue.
i tried to debug further by stripping down those methods. Somehow setting email attribute causes the error 206.
Earlier i had loggedInUser!["email"] = email
which i corrected to loggedInUser!.email = email
After loginWith call, a row is created in User object (authData (id and access_token not nil) and username attributes are updated) and below is state of loggedInUser
- sessionToken = nil
- isNew = true
- email = nil
- authenticated = true
If i assign value to email attribute before save call then fails with error 206 but save is successful if email is not updated.
Please see below code.
func loginWithFB() {
PFFacebookUtils.logInInBackground(withReadPermissions: facebookPermissions) {
(loggedInUser: PFUser?, error: Error?) in
if error == nil && loggedInUser != nil {
//this causes the issue
loggedInUser!.email = "[email protected]"
loggedInUser!.saveInBackground { (savedStatus, error) in
if error != nil {
logger.error("Enountered error \(error)")
} else {
logger.info("Saved successfully")
}
}
}
}
}
Thanks for reducing the code, this is interesting indeed. I will try to reproduce this issue.