User is not signed out even after FirebaseAuth.instance.signout is executed - flutter

I have a streambuilder that listens for auth changes. When i sign my user out using FirebaseAuth.instance.signOut(); it does seem to work. However, when i try to login with another user's credentials, the previous user's information is displayed instead.
However, I have noticed that when i hot restart my app in Android studio, the app resets itsefl and only then it presents me the new user's information.
How do i fix this?? It seems like my app's state needs to be reset after i signout, but I am not sure how to do this.
I am not storing any user value using shared prefs via provider, however i am using sharedprefs to store other information that helps the user filter information from listings.
Please advise.

Related

How to not show the Sign In page again if the user is already signed in in Flutter (Dart) and Firebase

I want to create a Sign in/Log in Page (with Google), but all the tutorials and videos only show how to log in and each time you open the app it asks you to log in. The desired way I want to have it is that If you are already logged in the sign in page shouldn't appear and if you are not signed in or the session has expired then the sign in page should ask you again. Can anyone help with this seeing as it's my first time working with Firebase and the Sign in function.
I have watched around 20 Youtube Videos and tried ChatGPT, but NO video shows you how to not make the page appear again if you are signed in or not. I tried writing an 'if' statement but my code was wonky and didn't work properly. I searched a lot of other places too but it's crazy that no one shows you how to do this -_-. If anyone knows some sort of documentation or a video that does show watchers how to do the desired effect please link it below or please share your code if you have successfully done this before. Much appreciated!
To have your app respond to the authentication state, you'll want to implement an authentication state listener like the one shown in the first snippet in the Firebase documentation on getting the current user.
Instead of calling listen, you can set the authStateChanges() as the stream for a StreamBuilder in your widget's build method.
Also see:
How to use .currentUser method in flutter (which includes a full code sample)
How Can I Get user id in Flutter with Firebase Authentication?

Should I consume IndexedDB directly when reloading a Flutter web app to determine auth state when using FirebaseAuth?

I am building a Flutter web app using FirebaseAuth for authentication, and I am trying to figure out how to load the correct route when the user a) is authenticated, and b) the user refreshes the web page.
When the app loads, firebase gets initialised and then fetches the user's auth state, returning it about 2 seconds later in an authStateChanges handler.
The problem I have is that by the time the auth state is returned, my app has already determined which route should be presented to the user, namely, login (since, as far as the app is concerned, the user is not yet authenticated).
This results in the user first being navigated to login, and then later, when the auth state is updated, they can be navigated somewhere else - which is a crappy UX.
In the Firebase Auth docs under the section "Persisting Authentication State" it says "The Firebase SDKs for all platforms provide out of the box support for ensuring that your user's authentication state is persisted across app restarts or page reloads" - and then goes on to say "On web platforms, the user's authentication state is stored in IndexedDB."
Does that mean, on page reloads, I need to access the auth state of the user directly from the IndexedDB? Or does it mean Firebase returns the value stored there for me automatically?
If I am supposed to consume IndexedDB directly, how do I do that, and what key should I use?
Firebase persists and restores the user's authentication state automatically. You don't need to do anything for that.
To respond to authentication state changes in your app, listen to onAuthStateChanged as shown in the first code snippet in the documentation on getting the current user. This method returns a stream, so if you want to show the current user in the UI, you can use a StreamBuilder.
then when firebase auth still determined if this user authenticated or not, instead of showing login page directly you can show the loading screen.
the easy way you can use go router.
and set :
GoRouter(
....
initialLocation: LoadingPage(),
redirect: _goTologinPageorHomePageBasedAuthStatus()
..)

How do i allow a user to stay logged in in flutter in the safest way?

I want a user to stay logged in after closing the app. I've heard of shared preferences but most of the examples are for things not as important as users' login credentials so is it possible to use that package for this? Furthermore, is that a safe way to go about this problem? Or should i allow google sign in, in order to keep them signed in? I'm generally unsure about how i should go about doing this and which is the safest way?
There are multiple ways to go around this problem.
1) Keeping login Data on the client side
You can use Shared Pref. Once logged in you can save a value in shared Pref or in your db. When the user comes again you can check the value, if sharedpref says user is loggedIn, take user to HomeScreen else login screen.
2) Keeping login data on your server.
You can use a web API to make sure if user is loggedin. When user login for first time you can store loginStatus on server. when user kills app and come back again you check with an API. if user was loggedIn. If user was loggedIn, take user to HomeScreen else login screen.
3) Using third Party APIs
As you already mentioned Google Sign In. You can certainly leverage that. It is a powerful and clean API. But most importantly check it with your business requirement and compliance team.

Parse & Swift - Preventing simultaneous logins - Parse Installation Object when user uninstalls app from phone

In order to solve a lot of problems I was having, I decided to prevent simultaneous logins by a single user. When a User signs into Parse, I check to see if there is an existing Installation with a Bool (isUserLoggedIn) set to true. If there is, the user is given a prompt to please logout of my app on all other devices before continuing. Once they do, they will be able to login.
This all working correctly.
However, I realized a potential issue. If the user logs into my app, and then deletes my app from their phone (before they logout), I never have the chance to set the Bool value in the Installation object to false. So, the user deletes the app, the Installation object (which contains their user objectId as well) still has the isUserLoggedIn Bool set to true.
When the user re-installs my app on their phone, and goes to login with their previously created account, my app won't let them login, because the prompt thinks that previous Installation is still logged in.
So, any ideas on how to solve this? I could solve it if I could get a persistent device ID, but apparently you can't do that anymore with iOS devices. Once my app is uninstalled, the device ID will change with the re-installation of my app.
I could also solve it, if Parse could delete the Installation object when the user uninstalls the app from their phone, but that doesn't seem possible either.
The last thing I thought of, was if there is a way to query installation objects with the users objectID, and for all of those returned, query the deviceToken for each device. Any deviceToken that is no longer valid, that must be the Installation object from the previous app installation, which I could then delete from Parse, solving my problem.
I'd really like to hear your ideas.
Thank you.
I ended up using Wain's suggestion from this question:
Handling Login on Multiple Devices using Parse iOS
I changed how I was tracking multiple installs (using the User class instead of the Installation class)

Auto- login in iphone

I've used NSUser Defaults in my app and generally it stores the user data while signing up and deletes those data while logging out. So, when the user signsup and then logs in, the stored data in NSUser Defaults makes the auto login part effective, even when the user closes the app and re opens it again.
But the problem is, when the user logs out, its asking him to signup again. What i want is that, if the user signsup, that information should be stored permenantly and when he signs out, it shouldnt ask him to signup again as it should only clear the memory of the login page , so that the other user can use the same app.
Iam using iOS 5. So, can i use SQLite database(to store the signedup info permenantly) and NSUser Defaults(to clear the memory of the login page) together in my app? Or is there any alternate solution to this?
If you are using an Auto login System and storing username and password you should be using the Keychain, not NSUSerDefaults
Read Here for more details about using the Keychain.
You can also use the keychain to control login sessions, Im not sure but i think even if the user deletes their app, the details stay in the keychain incase they reinstall the app
It seems that your app is offline and multiple users can signup and login in the same app (phone), so i think that best approach will be to save the signup data in sqlite database (you can use coredata)
and login info in NSUserDefaults. So when user logsout you just clear your NSUserDefaults value only. Also at login time you can check from your databases that user exist or not as all the users data who have signedup is stored in your database. Also if there is a functionality that user can delete his account, than just clear that user entry from the database.
Hope this helps....