I would like to discuss a paradigm that I am following for the authentication flow in a React Web App and need your advice / suggestions on the same.
The app has a button in the top right corner which is rendered conditionally based on user’s auth status. If a user is signed in, the button says Hi, first name on click of which the user can access protected routes else it’s just a Login button.
Current flow:
Every time user access the app, a spinner displays before rendering the actual route till user’s auth status is being detected by Firebase’s onAuthChanged() which takes a few seconds.
Once onAuthChanged()
conveys the auth status, app renders the route with the button in top right corner based on auth status.
Issue with the current flow:
Above mentioned flow doesn’t feel like a seemless experience for the user. Because every time user is accessing the app again or even refreshes its browser, it has to wait for that annoying spinner to go away. This is a pretty bad user experience.
Most of the app can be interacted irrespective of auth status, so it doesn't make sense to display a spinner across entire app even if it’s a public route just because auth status needs to be known in order to conditionally render that button. This flow makes the app completely unusable until the auth status is not detected by Firebase. Plus, as all the routes are lazy loaded, it adds up time for user to access app for first time with the 1st spinner being displayed as a fallback for lazy loading the route and the second one for the auth status.
Solution to current flow:
I have thought of a solution which can help me with above. What I am thinking now is to shimmer that button till the auth status is being detected by Firebase. And this seems like a pretty neat solution because now use can interact and browse the app while the button is being shimmered.
Drawbacks of the solution:
But this button is actually not alone in upper right corner and is accompanied by three other buttons as well which link to some other public routes. So, it’ll make UI quite inconsistent by shimmering only that one button, so I’m thinking that I can shimmer all four of them. But this even might seem annoying to user that the entire app loads quickly on refresh, but the upper 4 buttons still shimmer for few seconds and it cannot access any of those to access other public routes.
Alternate solution:
There’s a third and last iteration to the solution, in which I’m thinking to cache the auth status as a boolean check in local storage whether it’s logged in or not along with it’s first name. Now, the app will be totally seemless on browser refresh and repetitive app access.
Caveats:
But, let’s suppose the user has changed his first name on other device and user accesses the app on this browser, the button will show it’s old name cached in the local storage. To sync the name, I’ll have to store the updated name from onAuthChanged()
in local storage, update in redux from local storage and then display it on the button. Now, this will seem like a bug to user and might report as well because the old name will flash for a few seconds till the updated name doesn't come from the onAuthChanged()
CONCLUSION: I’d be like to know your views or if you have a better flow than these above. Thanks! :)