1) I'd suggest using repeatOnLifecycle when collecting flows in activities/fragments. There's several medium articles out there that also exemplify some nice wrappers around it to use to collect flows safely in views.
2) you can break out this property out of the global view state model and have it be its own flow so you only react to changes to that single property, rather then a global view state
3) if you just prefer to still emit a global view state from your VM, then you can update the collector (your activity) to something like
viewModel.uiState.map { it.authenicated }.distinctUntilChanged().collect { .... }
And if you wanted to specify some default value here and still use a State flow, then just tack on
stateIn()
before
collect()
It seems like the logic in your VM runs once then emits result so your UI shows the appropriate UI/composable given the authentication result. If this is something you want to only execute once, then it's still part of your app/view state, you may just want to call into the VM to
mark that you consumed and handled this state change.
Otherwise, it seems like how you have it written should already be fine, even if the view state was emitted several times due to other property changes but with the same authenticated value. Because compose is already smart enough to know if a property it's consuming changed or not and if needs to recalculate/redraw etc.