Compose/navigation component/lifecycle question. ...
# compose
c
Compose/navigation component/lifecycle question. My app has a home screen that is the main page. If your auth token is no longer valid. You are directed to the login screen. When you login, the login screen is popped and you see the home screen. But you see the "old" home screen. Is there anyway to manually clear my home VM and then when popping from the login screen the home screen reloads with the new auth token (which is potentially a new user altogether)
a
If the data in your Home VM depends on your current account, then that data should probably be updated when you sign in, which should automatically trigger a recomposition of your home screen (assuming that data is a state, or observed as such). Both your Home VM and Login VM could share a repository to access the current account.
c
Correct. But home screen is already in the backstack as per the navigation docs.
a
But when you bring it back, it should recompose on the new state, no?
c
It would work fine if I could clear the VM or backstack on logout. I need my VM to trigger a reload of data (network call) hence why I think I need a lifecycle event.
a
If you use LiveData or Flow, you could use a transformation to trigger your network call from your Home VM when the account changes I think. Something like what's documented on https://medium.com/androiddevelopers/livedata-with-coroutines-and-flow-part-iii-livedata-and-coroutines-patterns-592485a4a85a (the Suspend transformation sections). Otherwise, a solution might be to have a LaunchedEffect in your Home screen and trigger your refresh if the account known by your VM is different from the one in the repository.
c
Yeah. I guess my question is more so with if there's something blatantly wrong with my approach. I got my advice from Ian on how to set up login and so now I just have this one case that isn't handled.
i
Wouldn't your ViewModel be using a
currentUser
Flow provided by your
UserRepository
as its source of truth anyways?
c
So my HomeScreenViewModel does not observe my current user at all, but I think that's a nudge in the right direction. Going to add my AppUserManager to be injected
Copy code
@HiltViewModel
class HomeScreenViewModel
@Inject
constructor(
    var service: ApiService,
    private val appUserManager: AppUserManager
but my authToken is a state snapshot. I suppose that it shouldn't be a state snapshot and instead I need to learn how to use a Flowable here?
Copy code
var authToken by mutableStateOf(...
Okay. Swapped out mutableStateOf for StateFlow and now I have something working. I log out, then back in. And my homescreen is observing token changes, and when it changes it reloads. cool. okay. another mental model that didn't really connect in my head. makes sense for this to be driven by state instead of trying to hook into a lifecycle.
Thanks @Ian Lake!
Oh actually, Ian one last question. This entire scenario was with the HomeScreen. But what if I'm on my "Account" screen and I have a log out button. At that point... should I move the user to the HomeScreen and logout simulataneously so when they login they are back at home instead of the "Account" screen?
t
I think you should pop everything from the backstack when the user logging out
i
I would think that an explicit logout would also explicitly pop, yes. I would expect you'd want to treat that differently from something out of the user's control that invalidates their login (password change on another device, handling deep links when the user has never logged in, etc.)
c
I would think that an explicit logout would also explicitly pop, yes.
Hm. I wonder how I should shape this. I would explicitly popTo the login screen, but then the login screen would pop onSuccess and the user would be taken out of the app, no? Since my app is already setup like the "login" casestudy where the login screen always just pops on my network call success.
Ian, is there any docs on this sort of thing. I showed my team the "working" solution or the loggedIn state being consumed as a flow and therefore handling this sort of thing... but I can't find any docs that recommend a logout screen that pops everything but the sign-in screen.
At this point. I kind of think that having there be two ways to log out (revoked auth or manual logout) and two ways to log in (1. login the standard way of launching an app the first time > kicked to login > success == pop the login screen and 2. User manually logged out > popping everything and navigate to signin > on success == navigate to home) is more difficult.