-
Notifications
You must be signed in to change notification settings - Fork 35
User Manager
The app is configured with a UserManager that handles a single logged-in user from a centralized place.
Feel free to change the user model to match your app. Currently, we use a UserCredentials wrapper:
UserCredentials
-
User
- holds user info -
Credentials
- holds token and refresh token
- Stores the logged-in user on the device
- Notifies listeners of user changes
- Provides user actions:
- login
- logout
- update
- refresh
- deactivate
The user manager is a singleton component. To obtain the instance use the service locator: serviceLocator.get<UserManager>()
.
Prefer to execute all user actions through the UserManager so the user state can be maintained from a single centralized place. Avoid contacting the API service directly or modifying the user state outside UserManager.
An exception to this rule is when you end up having a circular dependency w/ UserManager. An example is the token refresh component that is part of the API service that UserManager depends on. To avoid this we provide the user storage separately: serviceLocator.get<Storage<UserCredentials>>()
. This will notify the user manager of any changes you make.
You can add your custom user actions in UserManager
You can provide your own Storage
implementation for storing the user. See SharedPrefsStorage
and SecureStorage
; just mind to wrap them in ObservedStorage
so the user manager can receive updates if modified externally.
The app UI is configured to automatically react to user changes (see AppRouterDelegate
)
- will navigate to the home screen upon login
- will navigate to the login screen on logout or session expiry upon 401 HTTP code when token refresh fails (see
UnauthorizedUserHandler
andUnauthorizedUserException
) - will load any saved user from disk and navigate to home or login screen accordingly
The user hooks offer a mechanism for other components to receive updates on important user events:
- postLogin: called when the user explicitly logs in [^1]
- postLogout: called when the user explicitly logs out [^2]
- onUserLoaded: called when the user, if any, is loaded from disk when the app starts
- onUserUpdatesProvided: provides user updates stream
This separates concerns when a component needs to perform an action based on a user event. For example, initialize and destroy user scope or set up Firebase. When using hooks the other components don't need to depend on UserManager or be contained and called from UserManager, which makes your code cleaner.
For user hooks in action, see: UserScopeHook
and FirebaseUserHook
[^1]: Not to be confused with subsequent app launches with a logged-in user.
[^2]: Not to be confused with session expiry.