stripe-android icon indicating copy to clipboard operation
stripe-android copied to clipboard

[BUG] CardInputWidget does not restore state properly with Compose

Open dabluck opened this issue 1 year ago • 7 comments

Summary

When #onRestoreState runs, the CardInputWidget breaks and nothing can be entered. Specifically I believe the internal cardNumberTextInputLayout has a width of 0 and therefore nothing can be entered. This is happening with jetpack compose although I'm not sure state restoration would be different without compose

Code to reproduce

Sample Repo Specific Code

Android version

Observed on Android 12 and Android 14 emulators but seems to be universal

Installation method

Gradle

Dependency Versions

kotlin: 1.9.0 stripe-android: 20.36.1 Android Gradle Plugin: 8.2.1 Gradle: 8.2

SDK classes

CardInputWidget

Video

stripe.webm

dabluck avatar Jan 17 '24 23:01 dabluck

Hi @dabluck 👋 Thanks for reporting this and double-thanks for providing a sample for reproducing the issue 🙏

We’ll have a look into that issue and let you know what we find.

tillh-stripe avatar Jan 18 '24 13:01 tillh-stripe

Just adding I am passing for the same issue. After a navigation event in a Compose application, backing to the screen where I have placed the CardInputWidget, this component is frozen. It looks like for some reason the state is not restored. Is there any update about the progress of this issue? Thanks in advance!

gabrielbmoro avatar Feb 13 '24 17:02 gabrielbmoro

Internal ref: https://jira.corp.stripe.com/browse/RUN_MOBILESDK-2878

You can avoid this state restoration issue by creating the CardInputWidget once (for example outside of compose), and passing it into the widget like so.

@Composable
private fun StripeWidget(
    stateHolder: SaveableStateHolder,
    cardInputWidget: CardInputWidget,
) {
    stateHolder.SaveableStateProvider("stripe_elements") {
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp)
        ) {
            Box {
                AndroidView(
                    modifier = Modifier
                        .fillMaxWidth(),
                    factory = {
                        cardInputWidget
                    },
                    update = {
                        // do nothing
                    },
                    onRelease = {
                    },
                )
            }
        }
    }
}

jaynewstrom-stripe avatar Mar 06 '24 17:03 jaynewstrom-stripe

Please reopen if you still have issues.

jaynewstrom-stripe avatar Mar 06 '24 17:03 jaynewstrom-stripe

@jaynewstrom-stripe That is a workaround for some cases but it's not a solution. The state restoration is broken. If for example the activity was torn down and recreated, creating it once is not possible.

dabluck avatar Mar 06 '24 17:03 dabluck

+1 to @dabluck's comment, unfortunately the suggested workaround isn't a viable long-term solution. Would really appreciate a fix for this, since it makes the widget unusable for our users 🙏

upside-sarah avatar Apr 23 '24 14:04 upside-sarah

@jaynewstrom-stripe , I tried the workaround you said, it did not work for me 😢

Do you have any other suggestion?

Ty in advance 🙏🏼

gabrielbmoro avatar Apr 24 '24 11:04 gabrielbmoro

This was fixed in https://github.com/stripe/stripe-android/pull/8543 and is in the latest release.

jaynewstrom-stripe avatar Jun 17 '24 17:06 jaynewstrom-stripe

@jaynewstrom-stripe Amazing, confirming that fix worked for us! Thanks for following up!

upside-sarah avatar Jun 17 '24 19:06 upside-sarah

Thank you so much for all the work to solve this issue 😀

gabrielbmoro avatar Jun 17 '24 19:06 gabrielbmoro