Proper way to handle Swift Firebase User Login state - ios

I've been looking around the web and trying to find out how to handle the user state of a logged in Firebase user where the following occurs:
User is already logged into the app.
Admin disable/delete the user from the Firebase Console.
User is still inside the app (although the account has been disabled/deleted on the Firebase Console).
After more than an hour, user is still inside the app. (Firebase ID token should have expired and addStateDidChangeListener() should've been called).
Currently, unless i call getIDTokenForcingRefresh() and signout() the user if the return error is due to disable/delete user. The user will still be logged in.
In summary, I've the following questions:
If a user is logged into the app, the user will remain logged in unless a signout() is called. It doesn't matter if the user account is disabled or deleted?
The Firebase ID token 1hour expiry only triggers the addStateDidChangeListener() but I'll have to handle what to do inside the handler?
What is the difference if I use reauthenticateWithCredential() to check for update state of the user?
Thanks for any clarification and help in advance! =)

I don't know if I will answer all of you questions but I can give you some info from my experience with Firebase.
As far as I know, if user gets deleted or disabled he will still be logged in app until token expires. Anytime you will try to manipulate with some data in Firebase (read, write, whatever) after the user has been disabled / deleted you will get an error in the result block. That is when you should check what kind of error it is and perform some actions. In this case, if error matched deleted / disabled user you should log him out and take to login screen. Here is a list of all errors.
reauthenticateWithCredential() is a way to do that but you will get the same error when reading other data from Firebase. So if a user is disabled, calling reauthenticateWithCredential() will return an error with code FIRAuthErrorCodeUserDisabled. That is how you detect that user was disabled.

Related

What is an AuthStateDidChangeListenerHandle?

I am looking at the documentation for Firebase Auth in order to get my native iOS app's authentication to work properly. I am having some trouble logging out of my application (the signed in user is still present in the auth() instance) and I have come across this code as a possible solution to why I can't sign out, but I don't understand the purpose of fit.
What is a AuthStateDidChangeListenerHandle? Is it to help you pass the user among different view controllers or is it to sign the user out?
handle = Auth.auth().addStateDidChangeListener { (auth, user) in
// ...
}
Auth.auth().removeStateDidChangeListener(handle!)
When you attach a handler with Auth.auth().addStateDidChangeHandler your completion handler will get called whenever the user's authentication state changes.
The most common case of this is when the application starts. Authenticating the user requires that the Firebase SDK calls to the Firebase servers to validate the user's credentials. This may take some time, so instead of blocking your application code (which would lead to a bad user experience), your code is allowed to continue, and Firebase handles this client-to-server call in the background. Then when the call completes it calls your auth state handler with the update authentication state for the user.
You can always call Auth.auth().currentUser to get the current authentication state of the user. But if you do this at application startup, the call to the server likely hasn't completed yet, and you'll get nil back, since there isn't an authenticated user. This may be exactly what you want (for example: to display the authentication state), but sometimes you'll actually want to wait until the authentication has completed (for example: if you want to navigate to a different screen where you allow the user to enter their credentials). In the latter case you'll want to use Auth.auth().addStateDidChangeHandler to wait for the authentication to complete, to ensure you only navigate to the next screen once you're sure the state is up to date.

flutter - How to keep user signed-in with Google

I have used Google Sign In to authenticate users with Firebase Auth, and I successfully get back my Firebase User. I want to keep the user authenticated, when they come back to the app. How can I do the same?
Users already stay authenticated. After you restart the app, Firebase reads the credentials from disk, and refreshes the user's token. Since this requires a roundtrip to the server, it happens asynchronously. So be sure to await _auth.currentUser() to get notified of the user's status.
Whenever I'm wondering how to do such things, I look at the FlutterFire sample app. This specific line can be found here.
Yes you need to do the auth.currentUser() function in order to keep users authenticated and the best part is that this function will work even if the user is offline, which makes it very versatile.

Reauthenticating logged in user after extended period of time

I'm using firebase authentication for my app and I have the users sign up, login, and log out all set up and going. However, I'm a little confused on how to manage the state of the users login status. Currently, if a user is logged into the app, but doesn't use the app for an extended period of time, firebase doesn't recognize them as logged in. I'm looking at the documentation and the approach is a bit unclear.
Should I be storing a FIRAuthCredential every time the user logs in, and then call reauthenticateWithCredential using that credential?
Firebase Auth only requires recent sign-in for sensitive operations like: deleting a user, changing a user's email or password. These are for obvious reasons. You want to make sure it is the same user before making such sensitive changes. Otherwise, the user is considered signed in indefinitely by the Firebase Auth backend (your assumption that "firebase doesn't recognize them as logged in" is not correct). Of course, a developer may also require re-auth before other operations like updating credit card, shipping address, etc. A developer would check the auth_time on the Firebase ID token. Only in such cases would you re-auth. You should never store credentials such as password on the client to avoid prompting the user to reauthenticate. It is needed to protect the user's account.
yes I think that is going to be right approach or second approach you can try is like when a user press login button instead of directly calling Authenticate User put a check in which last login timestamp value will be stored when user login compare timestamp value and then perform selected operation as you want . NOTE - you will be required to check weather user exist or not , but I think first approach will be better as if you had noticed in many Social apps like kik it ask for reauthentication after a long period of time but first it authenticate user instead of displaying home screen it take to reAuthenticate screen

How to block a specific user from your app?

I have an app that allows users to only log in through Facebook. The backend is Parse. I have many fake users creating accounts and screwing up my app, posting inappropriate things. Is there a way to block a list of Facebook accounts from logging in/using my app? I have the list of their Facebook IDs, but I am not sure how to block them by writing a Cloud Code.
Thank you in advance!
Simply add a new boolean column to your User table to indicate if this user is blocked/blacklisted. Every time a Facebook user gets a new session, their authData field needs to be updated. So you can use thebeforeSave trigger on Cloud to check if a user is blacklisted and return an error which prevents them from getting a new token and logging in at all.
Now to block a user, find their session record in the Session table and delete it which invalidates their token and logs them out. Then simply set their blocked field to true. They should not be able to log in to your app any more.

parse.com What's your authentication strategy on existing user accounts?

Context
I am using Parse.com as my backend for a mobile app. I use Facebook login only for now.
Assuming the user has logged in with Facebook and now has an account created on Parse already.
Question
Every time the user opens the app, should I do a check if his account is still valid by using PFUser.currentUser().become()? Or should I use the cached PFUser.currentUser()?
I have found out that if I delete the user account in the Parse backend, if I don't do a become(), the PFUser.currentUser() is still valid, even if the account does not exist anymore.
What is the best practice?
It's generally better to add a column to the user such as 'disabled', and when the app starts you can refresh the user, check that flag and display a message to the user and logout. That, from a user point of view, is similar to using become (at least as long as you check and notify the user).
So, you should do something if you're going to be removing or disabling users in the background. The main question is wether you fully delete the account or just delete the contents but leave the (empty) user in the system as a record.

Resources