mirzemehdi / KMPAuth

Kotlin Multiplatform Authentication Library targetting android and iOS
https://mirzemehdi.com/KMPAuth/
Apache License 2.0
230 stars 18 forks source link

[Google sign-in Android KO] With more than 5 Google accounts configured on the device #66

Open lopspower opened 2 weeks ago

lopspower commented 2 weeks ago

After several weeks of using this library on my apps, several users report that the “Google Sign-in” action doesn't work (nothing happens when you click). After a huge amount of investigation, what these users had in common was that they all had more than 5 Google accounts configured on their device. The problem is automatically corrected as soon as they delete a few accounts. Is it possible to make the action work regardless of the number of accounts installed on the device?

mirzemehdi commented 2 days ago

@lopspower this issue should be fixed as I remember.

In this PR(https://github.com/mirzemehdi/KMPAuth/pull/40), this is fixed by @bom-bakbang.

So basically what you need is to set filterByAuthorizedAccounts to true.

/**
     * @param filterByAuthorizedAccounts set to true so users can choose between available accounts to sign in.
     * setting to false list any accounts that have previously been used to sign in to your app.
     */
    public suspend fun signIn(filterByAuthorizedAccounts: Boolean): GoogleUser?

Attaching stackoverflow issue: https://stackoverflow.com/questions/78538579/new-google-credential-manager-is-throwing-a-transactiontoolargeexception

mirzemehdi commented 2 days ago

for now this field is not exposed in GoogleButtonUiContainer composable. But what you can do as a workaround is just copy its code from repo and copy paste as below:

@Composable
public fun GoogleButtonUiContainer(
    modifier: Modifier = Modifier,
    onGoogleSignInResult: (GoogleUser?) -> Unit,
    content: @Composable UiContainerScope.() -> Unit,
) {
    val googleAuthProvider = GoogleAuthProvider.get()
    val googleAuthUiProvider = googleAuthProvider.getUiProvider()
    val coroutineScope = rememberCoroutineScope()
    val updatedOnResultFunc by rememberUpdatedState(onGoogleSignInResult)

    val uiContainerScope = remember {
        object : UiContainerScope {
            override fun onClick() {
                println("GoogleUiButtonContainer is clicked")
                coroutineScope.launch {
                    //Pass true for filterByAuthorizedAccounts to avoid 5 Google Accounts issue
                    val googleUser = googleAuthUiProvider.signIn(filterByAuthorizedAccounts = true) 
                    updatedOnResultFunc(googleUser)
                }
            }
        }
    }
    Box(modifier = modifier) { uiContainerScope.content() }

}