I'm using Parse 1.7.1 for iOS and I am trying to sign up a user. I chose to let the user interact with the app before I force the sign up / login process. The problem is that as soon as I call signUp the session object disappears from the server and causes any subsequent calls to return error 209.
Here's some code:
AppDelegate:
[PFUser enableAutomaticUser];
[[PFUser currentUser] incrementKey:#"runCount"];
[[PFUser currentUser] saveInBackground];
When I check the Parse Core console I can see a valid User & Session.
MyController:
PFUser *user = [PFUser currentUser];
if (! user) {
user = [PFUser user];
}
user.email = #"my#email.com";
user.password = #"somepassword";
user.username = #"whatever";
// I also tried Save instead of signUpInBackground... same result
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"Success signing up");
}
else {
NSLog(#"Error %#", [error localizedDescription]);
}
}];
When I check the console there is an updated user but there is no Session anymore.
Any other API call
[Error]: invalid session token (Code: 209, Version: 1.7.1)
Despite the fact that the callback returns success as soon as I try to interact with the Parse API I get a 209, invalid session token. This is fair enough, since the session object is not present in the console.
Does anyone know what I am doing wrong?
Note: this a brand new app (not affected by the change made by Parse on the 25th of March)/.
I have raised this as a bug with Facebook and they are fixing it in 1.7.3
Here's the conversation I had with them.
Create button with selector -signUpSelector. And need implement this code:
-(void)signUpSelector
[PFUser becomeInBackground:#"session-token-here" block:^(PFUser *user, NSError *error) {
PFUser *newUser = nil;
if (error) {
newUser = [PFUser user];
} else {
newUser = user;
}
user.email = #"my#email.com";
user.password = #"somepassword";
user.username = #"whatever";
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"Success signing up");
}
else {
NSLog(#"Error %#", [error localizedDescription]);
}
}];
}];
Related
I have an app that checks whether the current session is valid. So if you change the password on another phone, it will log you out of your other phones when you open the app. So, If there is a session token cached into [PFUser currentUser] I want to becomeInBackground with that token, and if it returns an error then that session is invalid and we should log out, else its valid and we have a new sessionToken. When I run this code I do not get any errors, and a user is returned with (null) for a .sessionToken
NSLog(#"Current Token: %#", [PFUser currentUser].sessionToken);
if ([PFUser currentUser].sessionToken) {
[PFUser becomeInBackground:[PFUser currentUser].sessionToken block:^(PFUser * _Nullable user, NSError * _Nullable error) {
if (error) {
NSLog(#"%#", error);
} else {
NSLog(#"Returned User Token: %#", user.sessionToken);
}
}];
}
this returns
Current Token: r:36ff500b036c041a37h9bab21f308741
Returned User Token: (null)
It's deleting the currentUser sessionToken! I have the most current Parse SDK (1.12.0) and I have no idea why it's doing this to me.
I believe this is happening as you are instructing the ParseSDK to become that other user, which looks like it doesn't work if it's the same as the current user (i.e. your session is valid).
I handle the session check a little bit differently. Instead, I refresh the user, then trap any errors and check for an invalid session. This works well :)
[[PFUser currentUser] fetchInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (error) {
NSLog(#"Error refreshing user %#", error.localizedDescription);
// check if the session token is invalid... force a logout!
if ([error.domain isEqualToString:PFParseErrorDomain] && error.code == kPFErrorInvalidSessionToken) {
dispatch_async(dispatch_get_main_queue(), ^{
[PFUser logOut];
// Show your login screen or whatever here
});
}
return;
}
}];
I am trying to login in iOS using parse.com. But, during the login, an error is occurring every time. I found the solution for that, but still the error is continuing. My code is:
if (![self.phonnumber.text isEqual: #""]){
if(![self.emailtxt.text isEqual: #""])
{
NSString *userEmail = #"abc#gmail.com";//self.emailtxt.text;
NSString *userPassword = #"123";//self.phonnumber.text;
[PFUser logInWithUsernameInBackground:userEmail
password:userPassword block:^(PFUser *user, NSError *error)
{
if (!error) {
NSLog(#"succes");
} else {
// The login failed. Check error to see why.
}
}];
}
LoginwithUsername is expecting username not the email value.
[PFUser logInWithUsernameInBackground:#"frank" //username value in parse user table
password:#"123" block:^(PFUser *user, NSError *error)
{
if (!error) {
NSLog(#"succes");
} else {
// The login failed. Check error to see why.
}
}];
if you want to keep it working with email then while registration set email value against username and email both. and for display purpose if you need user name then set that in another key like displayName or FullName
I am using parse in an iOS app and there are two ways of signup, either using email/password or Facebook login.
The problem happen when a user sign up using his email/password then logout and try to sign up using his Facebook account which have the same email.
I am using [PFFacebookUtils logInInBackgroundWithReadPermissions:block: to signup with Facebook which creates a new user object in the Users table in Parse
Now I have two records for the same user and I can not update the record that has the Facebook information with the user email because Parse will not allow duplicate emails
So what should be the best solution to solve this problem?
UPDATE
I have used #kRiZ solution to login using plain Facebook code then either create new user or link the user with the Facebook data
- (void)loginWithFacebookWithSuccessCallback:(APISuccessCallback)successCallback
andFailureCallback:(APIFailureCallback)failureCallback {
// Login PFUser using Facebook
NSArray *permissionsArray = #[#"public_profile", #"email"];
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions: permissionsArray handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
failureCallback(error);
} else {
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:#"me?fields=id,first_name,last_name,email,gender" parameters:nil];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id fbResult, NSError *error) {
if (!error) {
NSString *email = result[#"email"];
User *existingUser = [self getUserByEmail:email];
if (existingUser == nil) {
[self signUpNewUserWithEmail:email];
} else {
// Need to set the current user to existingUser
}
[self linkCurrentWithAccessToken:result.token
successCallback(#{RESULT:RESULT_OK});
} else {
failureCallback(error);
}
}];
}
}];
}
Now the problem is to assign the [PFUser currentUser] to the existing user in case it is already exists
You can try linking the new Facebook user to an existing user on Parse using the [PFFacebookUtils linkUserInBackground:*... methods.
if (![PFFacebookUtils isLinkedWithUser:user]) {
[PFFacebookUtils linkUserInBackground:user withReadPermissions:nil block:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"Woohoo, user is linked with Facebook!");
}
}];
}
See Parse documentation on linking.
Login via Facebook (do not save user yet)
Query the user table for user having the same email as this new FB user
If found, link, else, save as new user.
UPDATE:
Linking method with FB access token:
[PFFacebookUtils linkUserInBackground:user
withAccessToken:accessToken
block:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"Woohoo, the user is linked with Facebook!");
}
}];
I am using Parse for my backend on my iOS application, and I am trying to use a FBLoginView to allow users to login with Facebook.
I am also trying to link the user's Facebook account to their Parse account. When I attempt to link the user to their FB by using
if (![PFFacebookUtils isLinkedWithUser:user]) {
[PFFacebookUtils linkUser:user permissions:nil block:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"Woohoo, user logged in with Facebook!");
}
}];
}
I receive an error telling me that the Facebook session is invalid. I have determined that the above code seems to be closing the Facebook session (when I comment out the code, the session does not close) and giving me the error. Does anyone have any experience with this error?
Do your other apps use Parse for the backend?
The user state stored in PFFacebookUtils is different from the user returned from the FBLoginView.
If your code looks like this:
#pragma mark FBLoginViewDelegate {
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
user:(id<FBGraphUser>)user {
// link current user
NSLog(#"User: %#", user);
if (![PFFacebookUtils isLinkedWithUser:user]) {
[PFFacebookUtils linkUser:user permissions:nil block:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"Woohoo, user logged in with Facebook!");
}
}];
}
}
Then you are currently linking a Facebook user object with a PFUser, which are incompatible. I would suggest using the data that the FBLoginView returns, and creating a parse user in the conventional way:
#pragma mark FBLoginViewDelegate {
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
user:(id<FBGraphUser>)user {
// link current user
NSLog(#"User: %#", user);
NSString *username = user[#"email"];
NSString *password = user[#"id"];
[PFUser logInWithUsernameInBackground:username password:password block:^(PFUser *user, NSError *error) {
NSLog(#"User: %#", user);
if (error.code == 101) {
// sign up
PFUser *user = [PFUser user];
user.username = username;
user.password = password;
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
}];
}
Now [PFUser currentUser] will return a parse user object, that was created based on your Facebook login. If the app is deleted/reinstalled, the next time the user enters the app, the FBLoginView will return a userid that will be used to log in to parse as an existing user.
Edit: A similar issue I've had is with using FBLogin, PFFacebookUtils, and any other recent facebook app logins if my phone has Facebook integrated into iOS settings. It seems to have something to do with the Apple integration of Facebook, and the new Facebook SDKs. It's annoying but I have to currently tell my users to delete their facebook information from the Settings, then they can login, using either PFFacebookUtils, or the process above. I hope this gets resolved soon.
for the first part of your question i'd found a way to login user into my app by just using Facebook with Parse. Actually once the users use this, you can check the data browser of your app and check the auth data filed and the profile filed with all the fb data that i did request within the app.
here is the code i use to login with fb, haven't linked a previous user with a fb account
- (IBAction)loginButtonTouchHandler:(id)sender {
// The permissions requested from the user
NSArray *permissionsArray = #[ #"user_about_me", #"user_relationships", #"user_birthday", #"user_location"];
// Login PFUser using Facebook
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
//[_activityIndicator stopAnimating]; // Hide loading indicator
if (!user) {
if (!error) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
} else {
NSLog(#"Uh oh. An error occurred: %#", error);
}
} else if (user.isNew) {
NSLog(#"User with facebook signed up and logged in!");
//Go to your next view
} else {
NSLog(#"User with facebook logged in!");
//Go to your next view
}
}];
}
Hope this helps!
I'm using Parse on ios; this is my third app using Parse, but the first one where I've used the anonymous user functions.
I'm trying to convert an anonymous user to a regular user:
[PFAnonymousUtils logInWithBlock:^(PFUser *user, NSError *error) {
if (error) {
DLog(#"Anonymous login failed.");
handler(NO, #"anonymous login failed");
} else {
DLog(#"Anonymous user logged in.");
MyParseUser *myUser = [MyParseUser currentUser];
if ([PFAnonymousUtils isLinkedWithUser:myUser]) {
DLog(#"still anonymous");
} else {
DLog(#"not anonymous");
}
[myUser setParseUserForInstallation]; // usually overkill
NSString *username = myUser.username;
NSString *pass = #"password";
myUser.password = pass;
DLog(#"Anonymous user has username %#, password %#", username, pass);
[(PFUser*)myUser signUpInBackgroundWithBlock:^(BOOL success, NSError *error) {
if (success) {
DLog(#"signup succeeded");
handler(YES, myUser);
} else if (error) {
DLog(#"Uh oh. An error occurred: %#", error);
handler(NO, error);
} else {
DLog(#"signup didn't throw error, but user not created correctly");
handler(NO, nil);
}
}];
}
}];
...but signUpInBackgroundWithBlock is causing an exception:
"Cannot sign up an existing user."
Why?
Turns out there's one and only one username string that is not valid for an anonymous user to have when calling signUpInBackgroundWithBlock: the one it already has! Parse seems to consider the anonymous and non-anonymous users to be separate, so just like two regular users, they can't share the same username. This fixed it:
NSString *username = [MyParseUser randomStringWithLength:10];
myUser.username = username;
(details of random string creator not important here)