0

I am trying to migrate to the new Google SignIn with Credential Manager.

Following the documentation and ending up with this integration:

val option = GetGoogleIdOption.Builder()
    .setFilterByAuthorizedAccounts(false)
    .setServerClientId(WEB_CLIENT_ID)
    .setAutoSelectEnabled(false)
    .build()

val request = GetCredentialRequest.Builder()
    .addCredentialOption(option)
    .build()

val manager = CredentialManager.create(this)
lifecycleScope.launch {
    try {
        val credential = manager.getCredential(this@MyActivity, request)
        print(credential)
    }

    catch (exception: GetCredentialException) {
        println(exception)
    }
}

Now, this seems to work on an emulator. It also works on my physical phone WHEN I setFilterByAuthorizedAccounts to true. However, when I do setFilterByAuthorizedAccounts to false and I try to getCredential, it throws the following exception:

Second failure launching com.android.credentialmanager/.CredentialSelectorActivity, giving up (Ask Gemini)
android.os.TransactionTooLargeException: data parcel size 609076 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(BinderProxy.java:586)
at android.app.IApplicationThread$Stub$Proxy.scheduleTransaction(IApplicationThread.java:1977)
at android.app.servertransaction.ClientTransaction.schedule(ClientTransaction.java:178)
at com.android.server.wm.ClientLifecycleManager.scheduleTransaction(ClientLifecycleManager.java:65)
at com.android.server.wm.ClientLifecycleManager.scheduleTransactionAndLifecycleItems(ClientLifecycleManager.java:143)
at com.android.server.wm.ActivityTaskSupervisor.realStartActivityLocked(ActivityTaskSupervisor.java:956)
at com.android.server.wm.RootWindowContainer$AttachApplicationHelper.test(RootWindowContainer.java:3805)
at com.android.server.wm.RootWindowContainer$AttachApplicationHelper.test(RootWindowContainer.java:3755)
at com.android.server.wm.ActivityRecord.forAllActivities(ActivityRecord.java:4743)
at com.android.server.wm.WindowContainer.forAllActivities(WindowContainer.java:1831)
at com.android.server.wm.WindowContainer.forAllActivities(WindowContainer.java:1825)
at com.android.server.wm.RootWindowContainer$AttachApplicationHelper.accept(RootWindowContainer.java:3793)
at com.android.server.wm.RootWindowContainer$AttachApplicationHelper.accept(RootWindowContainer.java:3755)
at com.android.server.wm.Task.forAllRootTasks(Task.java:3198)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2212)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2212)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2212)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2212)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2212)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2212)
at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2205)
at com.android.server.wm.RootWindowContainer$AttachApplicationHelper.process(RootWindowContainer.java:3771)
at com.android.server.wm.RootWindowContainer.attachApplication(RootWindowContainer.java:1858)
at com.android.server.wm.ActivityTaskManagerService$LocalService.attachApplication(ActivityTaskManagerService.java:6582)
at com.android.server.am.ActivityManagerService.finishAttachApplicationInner(ActivityManagerService.java:4904)
at com.android.server.am.ActivityManagerService.finishAttachApplication(ActivityManagerService.java:5006)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2750)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2798)
at android.os.Binder.execTransactInternal(Binder.java:1496)
at android.os.Binder.execTransact(Binder.java:1440)

The way I see it is that because I'm setting the setFilterByAuthorizedAccounts to false, then the Credential Manager is trying to get a lot more accounts and is causing this TransactionTooLargeException. The max Parcel size is 500KB and in this case, the Parcel size is around 600KB, causing the Exception.

Now, my question is - besides reporting this issue and waiting for a fix, is there anything I can do to overcome it? Maybe increase the Transaction max size?

3
  • Can I ask how many google accounts are on that device? And what Android version is on that device?
    – Ali Naddaf
    Commented Jun 1 at 14:35
  • @AliNaddaf it is a Google Pixel Pro 7 and it has 5 Google accounts.
    – Ravers
    Commented Jun 2 at 9:45
  • Please create a full bug report and open an issue so we can address that; it shouldn't happen.
    – Ali Naddaf
    Commented Jun 2 at 13:34

1 Answer 1

2

TransactionTooLargeException raises when transactional data is too large.

You can't adjusting the Transaction max size, as far as Android is concerned, as the security measures and performance constrictions do not allow that.


Alternatively you can do :

1. Filter by Account Name :

That is, if it is possible in your use case, you can try to filter by account name instead of turning off setFilterByAuthorizedAccounts. This could come in handy in reducing the number of accounts that one needs to sift through in the Credential Manager:

val option = GetGoogleIdOption.Builder()
    .setFilterByAccountName(accountName) 
    .setServerClientId(WEB_CLIENT_ID)
    .setAutoSelectEnabled(false)
    .build()

2. Multi-Step Credential Selection :

  • If filtering isn't feasible, consider a multi-step credential selection process:
  • First, invoke the getCredential method with only the setFilterByAuthorizedAccounts parameter set to true.
  • If no credential is found or the user wishes to explore further, a UI should be created to list all the Google accounts possible.
  • The method getCredential should be invoked again for the selected account after setting the drop down for the account and the GetGoogleIdOption to the desired one.

It is more flexible but requires more development effort in UI, and the exception is expected to be eliminated by this approach.

3. Manual Account Selection :

You could consider a manual account selection flow: Show alert with message to the user for navigating to the system settings and manually select Google account for sign-in.

This is less user friendly but might be suitable for specific scenarios where account selection is infrequent or requires additional user permission.

Notes:

  • However, you can try the approaches mentioned below until there is a probable solution to the issue: One can use either approach 1 or 2 based on the specific scenario. These provide a middle ground that functions as a solution but does not include an exception. Notify Google to the problem through certain resources as bug tracker to have more people concerned about the issue.
  • Also, do not forget about the positive user experience while using other methods. It is urgently important to have a simple and user-friendly sign-in process to the site.
  • It is recommended to check for libraries or frameworks that might exist and provide Google Sign-in coupled with Credential Manager with integrations since some of these complexities are within them.

Reference links

Not the answer you're looking for? Browse other questions tagged or ask your own question.