-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Authenticator] Improve documentation regarding navigation #140
Comments
Hey @pmellaaho thanks for filing your question! Authenticator is not overly opinionated about how it is integrated into your application, so there is no single recommended approach, as it will be different for different use cases. Option 1 is certainly the easiest way. I'm not sure I fully understand your issue (colors should be read from the theme without issue) but if there are wrappers that you need that are only applied at screen level then I would agree this isn't quite what you want to do. One thing to note is that you don't really need to pass around the If you do want to access the @Composable
fun MyApplication() {
val authenticatorState = rememberAuthenticatorState()
val stepState = authenticatorState.stepState
if (stepState is SignedInState) {
MyApplicationContent(stepState)
} else {
AuthenticatorScreen(authenticatorState)
}
}
@Composable
fun AuthenticatorScreen(authenticatorState: AuthenticatorState) {
Authenticator(state = authenticatorState) {
// no need to show content here, Authenticator only visible when stepState != SignedInState
}
} Hope that helps! |
Thank you for very fast response. The issue on option 1 is that it's not enough to just place the Authenticator under application theme and expect the Authenticator to use it. So, something like this is needed to make it work: This is because Surface uses default values (colour, content colour) from theme to apply correct colours. This is just a small detail but maybe you could fix it in Theming chapter I was referring to. Option 2 might be a bit more appealing because we would be using the standard Jetpack Compose Navigation way of doing things and even use transitions. I however have doubts because I think that Authenticator might not be able to do it's magic if it's only present in the one navigation target? For example, is it able to renew the access token automatically or take user to SignIn if tokens have expired. Maybe I would indeed need to observe AuthenticatorState as shown in your code above and do manual navigation to AuthenticatorScreen when needed. |
Thank you for the clarification, I understand better now. Authenticator does not assume how to best fit into your theme, this is intentional. I'll make a note to tweak the documentation appropriately. For your second point, the Furthermore, as long as Alternatively, you can even instead choose to listen directly to Amplify Auth Events yourself instead of using AuthenticatorState, as this is what that class is doing internally. |
Thank you for the advice, I think it's great idea to listen to Auth events directly! I continued experimenting with the both approaches discussed above but I think they both suffer from same issues. Let's imagine the following user story:
Do you agree that my findings indicate that there is a problem and I should file another issue for it? |
Hey @pmellaaho. I think in the scenario you described the actual issue is in step 3, you should not be shown the This appears to be a bug in the Amplify Auth library, and there is already an outstanding GitHub issue open for it: aws-amplify/amplify-android#2783. I would recommend following that issue for updates, and I'll ping the team to see if we can make some progress there. |
Ok, this is good to know and thanks for letting them know that I'm also interested in getting this resolved! |
I've tested scenarios similar to those mentioned by @pmellaaho using AmplifyUIAuthenticator v1.2.2 and AmplifyCore v2.21.0. Preconditions:
Scenario 1:
Observed behavior in scenario 1:
Scenario 2:
Observed behavior in scenario 2:
Questions:
|
Hi @JOikarinen. I would say that the scenarios you describe are not expected behaviour. Both of the scenarios are related to the information returned from Amplify, as the logic of whether to show the Sign In screen is driven off the Just to confirm, when you say you were using "AmplifyCore" 2.21.0, you explicitly added a dependency like the following? The fix was in the Cognito plugin so you'd need this specific dependency. implementation("com.amplifyframework:aws-auth-cognito:2.21.0") |
Thanks @mattcreaser for the quick response. In my experiment I didn't explicitly add the
With the dependency setup above, Scenario 2 now returns I guess that things might start working correctly once a version of |
@mattcreaser |
I've retested scenarios mentioned above (i.e. scenario 1 and scenario 2) using AmplifyUIAuthenticator v1.3.0 and AmplifyCore v2.21.1. I can confirm both scenarios now work as expected. |
Before creating a new issue, please confirm:
Which UI component?
Authenticator
Gradle script dependencies
Environment information
Please include any relevant guides or documentation you're referencing
https://ui.docs.amplify.aws/android/connected-components/authenticator https://ui.docs.amplify.aws/android/connected-components/authenticator/customization#theming https://github.com/aws-amplify/amplify-ui-android/blob/main/samples/authenticator/app/src/main/java/com/amplifyframework/ui/sample/authenticator/MainActivity.kt https://developer.android.com/develop/ui/compose/navigation
Describe the bug
What is the correct way to add Authenticator if you working on a Compose Android App that uses Jetpack Compose Navigation component?
It seems to me that there is conflicting and misleading documentation and code samples in the referred sources. There are basically two approaches that one can take:
Follow the sample code in the Theming documentation
In this case the whole application would be wrapped inside Authenticator and the MainActivity code would look something like this:
MyApplicationTheme { Authenticator( signInContent = { signInState -> SignInScreen(signInState) } ) { state -> val navController: NavHostController = rememberNavController() MyAppNavHost( authenticatorState = state, navController = navController ) } }
Follow the Authenticator sample code in GitHub
In this case we would use the mechanisms available in Compose navigation component and define e.g. AuthenticatorScreen() as a startDestination (= Authenticator.route) in NavHost. AuthenticatorScreen() would look something like this:
`@Composable
fun AuthenticatorScreen(
onShowSignedInContent: () -> Unit
) {
Scaffold { padding ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(padding)
) {
Authenticator(
modifier = Modifier.fillMaxWidth(),
signInContent = { signInState -> SignInScreen(signInState) }
) { state ->
val activity = (LocalContext.current as? Activity)
(activity as MainActivity).signedInState = state
onShowSignedInContent()
}
}
}
}
And passed onShowSignedInContent lambda would do the navigating:
onShowSignedInContent = { navController.navigate(Main.route) }
In this case we have store signedInState somewhere because it can’t be passed as navigation argument.
Also, the screen containing the SignOut -action would receive the following lambda as parameter:
onSignOutClick = {
(activity as MainActivity).signedInState?.signOut()
navController.navigateSingleTopTo(Authenticator.route)
}`
I started experimenting with the 1) but noticed that there is a problem because Authenticator is not placed inside e.g. Scaffold that applies the correct colours from theme and I can’t really do that when using Compose navigation i.e. it’s included in Screen level composables. I then moved to 2) approach which seems to work but are there caveats in the way that you’re aware of? Also, there should be an API (e.g. Amplify.Auth.fetchCurrentState()) to fetch the current state to avoid need to store it in way shown above code.
So, the question is, which approach is the recommended one?
Reproduction steps (if applicable)
No response
Code Snippet
// Put your code below this line.
Log output
amplifyconfiguration.json
No response
Additional information and screenshots
No response
The text was updated successfully, but these errors were encountered: