Parse, how to handle an invalid session? - ios

Straight from the documentation, it says that:
PFUser#currentUser() gets the currently logged in user from disk and
returns an instance of it.
This is fine and all, but what if the user logged in # disk isn't a user that's logged in on the server. Lets say the users account has been deleted for whatever reason, or the session is no longer valid due to database modifications. These are currently the problems that I'm facing.
Throughout the tutorials that I've read, I've seen using the following line of code as a way to check if the user is valid, and thus you can skip the login stage of the application:
if let user = PFUser.currentUser() as? Subclass {
// Simulate successful login
}
However, this is posing a problem for me, as the successful login is simulated, but the login was not successful. Here is the error I'm dealing with:
[Error]: invalid session token (Code: 209, Version: 1.12.0)
So the first thing I did was attempt to log the user out, however this fails (I assume because the user wasn't logged in to begin with) and now I'm thrown into application which immediately crashes because the data required by the server isn't there. Here's how I attempted to handle error code 209:
let query = PFQuery(className: "Foo")
query.whereKey("Bar", equalTo: "Foo")
query.findObjectsInBackgroundWithBlock {
(foo, error) -> Void in
if let error = error {
print(error);
if error.code == 209 {
PFUser.logOutInBackgroundWithBlock {
(error) -> Void in
if let error = error {
print("Okay, I'm trapped!");
}
}
}
}
}
The output of this "query" is the following:
[Error]: invalid session token (Code: 209, Version: 1.12.0)
Okay, I'm trapped!
I'm out of ideas over here, and I'm ripping my hair out trying to figure out how to properly validate a user upon application launch. It seems redundant to have to catch error code 209 on every query, but if that's what you have to do, then that's what you have to do.

You can use synchronous logout. So even if error occurs, it doesn't matter. The PFUser session token will be invalidated if the user launches the app again.
Also latest Parse SDK provides PFConstants class, which provides enum for all possible error cases.
kPFErrorInvalidSessionToken = 209.
if (error.code == kPFErrorInvalidSessionToken) {
PFUser.logOut()
//Necessary pop of view controllers after executing the previous code.
}

Related

SQRDReaderSDK.shared.authorize() doesn't have callback initially

I currently am unable to authorize the SquareReaserSDK with iOS (Swift).
I have a node instance that takes in an access_token.
I then call listLocations()
I provide the first location_id in the body of a CreateMobileAuthorizationCodeRequest()
I then pass the resulting mobile auth code to the client
After successfully retrieving a mobile auth token and providing that to the below, the first time this is called there is no callback. The block if statement never fires.
Redundant calls results in an authorization_already_in_progress error (the if statement is fired).
SQRDReaderSDK.shared.authorize(withCode: mobileAuthToken) { location, error in
if let authError = error {
print("Authorize SquareReaderSDK", authError.localizedDescription)
} else {
print("Authorize SquareReaderSDK", location)
Defaults[.establishment]?.squareMobileAuthToken = mobileAuthToken as! String
}
}
authorize() endpoint reference: https://developer.squareup.com/docs/api/reader/ios/Classes/SQRDReaderSDK.html#/Authorization
Redundant calls results in:
vvvvv SQUARE ERROR vvvvv
ERROR: Something went wrong. Please contact the developer of this application and provide them with this error code: authorization_already_in_progress
DEBUG CODE: authorization_already_in_progress
DEBUG MESSAGE: Authorization is already in progress. Please wait for SQRDReaderSDK.shared.authorize() to complete.
^^^^^ SQUARE ERROR ^^^^^
At any point while trying to authorize the device, I get the following error when trying to present the checkoutController:
Checkout Failed:
This device is not currently authorized to accept payments with Square.

Why does logging out user from firebase require error handling, but not getting current user?

I'm a bit new to error handling in swift. After going through multiple firebase tutorials I've become accustomed to mindlessly writing out my error handlers without understanding why they are required for certain cases and not required for others. I know that any time an error can be thrown, I must handle the error but I don't always know why an error might be thrown in the first place.
Why do we not need an error handler when getting the current user?
guard let currentUser = FIRAuth.auth()?.currentUser else {return}
But we do need one for signing out a user?
func logout() {
if FIRAuth.auth()?.currentUser != nil {
// there is a user signed in
do {
try? FIRAuth.auth()?.signOut()
} catch {
print("failed to sign out user")
}
}
Don't both have the potential to throw errors?
Signing out is really just a matter of forgetting whatever tokens were previously in place that identified the user. Nothing else really needs to happen that could "fail" and prevent the signout from finishing.

Invalid session toked after deleting a user Parse Server Swift

Im running Parse Server on heroku and mLab and I use the following code to delete a user:
if PFUser.current() != nil {
PFUser.current()?.deleteInBackground(block: { (success, error) in
if error == nil {
self.performSegue(withIdentifier: "unwindToLoginFromSignUp", sender: self)
} else {
// Handle error
}
})
}
The issue is that after deleting a user if I create a new user I get the error "Invalid session token (Code: 209, Version: 1.14.2)". I understand what a session toked is but I'm not sure how I should be handling it when I delete a user.
Also the error does not cause a crash, it just shows up in the console. Any help is much appreciated!
I think you should store the currentUser object then log out the user first, and then delete the currentUser.
Once you delete the user without deleting the session, the app won't know that the current user doesn't exist any more, the session still remains, therefore you will get a session error after signing up another user.
But if you log out the user first, the current session will also be deleted, then you are free to create a new user.
I realized I forgot to log the user out after deleting their account and taking them back to the sigh up view.

Delete user in iOS using Parse login

I'm implementing parse login in iOS using swift. From a login view controller i get new users to signup via swift using just email and password. This creates a PFUser which correctly saves to Parse backend. The user is then taken to a UserDetails view controller to "complete" their signup by providing more details which gets saved to coredata (im using parse functionality just for the signup). If the user cancels however before "completing" the additional details, I want to delete the PFUser from parse created possibly moments earlier. In the UserDetails view controller under cancelTapped ibaction im running code
if PFUser.currentUser() != nil {
PFUser.currentUser()?.deleteInBackgroundWithBlock({ (deleteSuccessful, error) -> Void in
print("success = \(deleteSuccessful)")
})
//user deleted in background block above but still logged in so now logout
PFUser.logOut()
}
but im getting following parse error [Error]: User cannot be deleted unless they have been authenticated. (Code: 206, Version: 1.8.5) .... i dont know what authentication process is needed and im guessing the problem could be because im trying to delete a user before parse has had a proper time to create the user in the first place .... any help or suggestions appreciated
User ALC permission automatically blocks anyone else from performing a write/delete on your record. This means you must be logged in if you want to update/delete your own record. In your code, you probably log out before your asynchronous delete code gets a chance to run in the background. Instead you need to log the user out after the delete was successful in the completion block of deleteInBackgroundWithBlock function.
if PFUser.currentUser() != nil {
PFUser.currentUser()?.deleteInBackgroundWithBlock({ (deleteSuccessful, error) -> Void in
print("success = \(deleteSuccessful)")
PFUser.logOut()
})
}

Logout user when deleted from Parse data browser

I have a couple hundred users that I need to remove from my parse app. However, when I delete the user accounts the users are still able to use the app fully without a problem. Is there anyway to "force" the logout remotely? Or what else would you suggest? Thanks!
It sounds like the user is being cached on the device and I don't think parse has a remote way to clear cached data on there. I like to put a user refresh(now fetch since refresh is deprecated) function when app opens to get the latest data for that user.
You could put a fetch function when the app opens and if it returns a specific error, it would mean the user doesn't exist and then set the current user to nil. I'm not sure which error it returns and I'm at work so I can't try it right now. I would hope that if the user doesn't exist, it would return kPFErrorUserWithEmailNotFound = 205...
Here are the error codes: https://parse.com/docs/ios/api/Constants/PFErrorCode.html
You will have to give it a try but I am thinking something like this (sudo-code):
post.fetchIfNeededInBackgroundWithBlock {
(post: PFObject?, error: NSError?) -> Void in
if let someError = error {
if someError = kPFErrorUserWithEmailNotFound {
// User doesn't exist!
}
} else {
// User exists and is fetched successfully
}
}

Resources