Today I've started playing with Android's Navigation Component to implement authentication flow in my app. The idea is very simple: a user launches the app and it displays one piece of UI if she's authenticated and another if she's not.
What I've done is in my HomeFragment
's onViewCreated
method I check if a user is authenticated and if she's not I call the NavController
's navigate()
method by passing it the id of an action that will navigate to the AuthenticationFragment
. Everything works fine until a user clicks the back button while in AuthenticationFragment
, because then I get this error. I still have no idea what's the actual reason for that error, but the idea of navigation happening too quickly seems similar to my case: the destinations first switch from AuthenticationFragment
to HomeFragment
and then immediately from HomeFragment
to AuthenticationFragment
again, because HomeFragment
finds out again that a user is not authenticated.
Despite of the error I'm getting, this approach still seems wrong to me. The user shouldn't be able to go back to the HomeFragment
(and see the screen flicker when fragments are immediately switching back and forth) before she authenticates. I've also looked at this Android's official guide to implementing an authentication flow, but it too seems wrong to me, because a redundant third piece of UI is involved there (the MainFragment
). I could replace it with a splash screen in my case, but it would still stay in the back stack and the user would be able to go back to splash screen, which is obviously nonsense.
So what would be the correct way to implement an authentication flow using the Android's new Navigation Component? The functionality I want is: if a user is not authenticated, then she's redirected to an authentication UI and if she presses the back button from there she should exit the application.
UPDATE: I know I could just listen to the back press event and close the application from there, but I still hope there's some elegant solution using Android's Navigation Component.
Typically the flow will look like this: The user opens the app. The app loads some authentication state from persistent storage (for example, AsyncStorage ). When the state has loaded, the user is presented with either authentication screens or the main app, depending on whether valid authentication state was loaded.
A login flow is handled independently from the app's main navigation flow. To authenticate, the app must navigate to the login_fragment, where the user can enter a username and password to authenticate. If accepted, the user is sent back to the profile_fragment screen.
Most apps require that a user authenticate in some way to have access to data associated with a user or other private content. Typically the flow will look like this: The app loads some authentication state from encrypted persistent storage (for example, SecureStore ).
Figure 1. A login flow is handled independently from the app's main navigation flow. To authenticate, the app must navigate to the login_fragment, where the user can enter a username and password to authenticate. If accepted, the user is sent back to the profile_fragment screen.
In your login fragment, you need to declare "Pop up-to" action from home fragment.
"popUpToInclusive = true" pops the given destination from backstack
<fragment
android:id="@+id/loginFragment"
android:name="com.example.navigationsample.fragments.Login"
android:label="Login_Fragment"
tools:layout="@layout/layout_login">
<action
android:id="@+id/action_loginFragment_to_homeFragment"
app:destination="@id/homeFragment"
app:popUpTo="@id/loginFragment"
app:popUpToInclusive="true"/>
</fragment>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With