stevdza-san / OneTapCompose

This library allow you to easily integrate One-Tap Sign in with Google(Credential Manager) in your project with Jetpack Compose. It keeps away all the boilerplate code.
Apache License 2.0
176 stars 15 forks source link

Don't show the signin popup every time #30

Closed eric-nextsense closed 1 month ago

eric-nextsense commented 1 month ago

The code works well to show the popup and get the user details. However it shows the popup every time the user opens the app, i would prefer if they don't have to do that, is it possible?

I did notice this error in the log, maybe its related?

2024-05-03 12:02:56.830 25989-26002 AuthPII com.google.android.gms.persistent E [RequestTokenManager] getToken() -> BAD_AUTHENTICATION. App: <....>, Service: oauth2:openid ajxu: Long live credential not available. at tzn.a(:com.google.android.gms@240812038@24.08.12 (190400-608507424):1003) at tzt.b(:com.google.android.gms@240812038@24.08.12 (190400-608507424):28) at tzr.a(:com.google.android.gms@240812038@24.08.12 (190400-608507424):620) at tsv.h(:com.google.android.gms@240812038@24.08.12 (190400-608507424):3) at yep.i(:com.google.android.gms@240812038@24.08.12 (190400-608507424):19) at yep.fL(:com.google.android.gms@240812038@24.08.12 (190400-608507424):1355) at ocn.onTransact(:com.google.android.gms@240812038@24.08.12 (190400-608507424):96) at android.os.Binder.transact(Binder.java:1341) at bgbi.onTransact(:com.google.android.gms@240812038@24.08.12 (190400-608507424):10) at android.os.Binder.transact(Binder.java:1341) at aynx.onTransact(:com.google.android.gms@240812038@24.08.12 (190400-608507424):147) at android.os.Binder.execTransactInternal(Binder.java:1496) at android.os.Binder.execTransact(Binder.java:1440)

eric-nextsense commented 1 month ago

Here is the code i use:

                    val state = rememberOneTapSignInState()
                    var user: GoogleUser? by remember { mutableStateOf(null) }
                    OneTapSignInWithGoogle(
                        state = state,
                        clientId = stringResource(R.string.web_client_id),
                        rememberAccount = true,
                        onTokenIdReceived = {
                            user = getUserFromTokenId(tokenId = it)
                            Log.d("MainActivity", user.toString())
                            goToHomeActivity()
                            finish()
                        },
                        onDialogDismissed = {
                            Log.d("MainActivity", it)
                        }
                    )
stevdza-san commented 1 month ago

@eric-nextsense Where exactly are you calling an "open()" function? Double check if it's properly handled as side-effect if inside the composable function.

eric-nextsense commented 1 month ago

This is right after the other code inside the setContent() I tried either using the button or auto-calling it with "state.open()" as you can see here.

                    Box(
                        modifier = Modifier.fillMaxSize(),
                        contentAlignment = Alignment.Center
                    ) {
                        Button(onClick = { state.open() }) {
                            Row(verticalAlignment = Alignment.CenterVertically) {
                                if (state.opened) {
                                    CircularProgressIndicator(
                                        color = Color.White
                                    )
                                }
                                Spacer(modifier = Modifier.width(8.dp))
                                Text(text = "Sign in")
                            }
                        }
                    }
                    state.open()
stevdza-san commented 1 month ago

You should call the open() function in the onClick() parameter of a button, so that the user can trigger it only once. The above code would probably trigger the open() function multiple times, as much as your composable recomposes.

eric-nextsense commented 1 month ago

Thats not the issue here. What i want is: 1) user opens the app the first time. They sign-in and choose their user from the popup. 2) user exits the app 3) user comes back to the app,. they are logged in without having to choose their user again.

Right now in 3), it asks them to select their user every time. Does not matter the open() is called automatically or from the button.

stevdza-san commented 1 month ago

That case is not handled by this library by default. Instead you need to save a simple boolean value in a DataStore for example, to indicate that the user is authenticated already. And based on that value either navigate to an Auth screen or proceed with your app. Along the way you can also persist the user info as well.

eric-nextsense commented 1 month ago

ok i see, might need to add a check if the token is still valid too.