stripe-react-native: CardField components crashes app on Android when rendered in Modal.

Describe the bug

When rendering a CardField in a React Native modal on Android, the app crashes, but is fine on iOS.

To Reproduce Steps to reproduce the behavior:

  1. Clone this repo:

https://github.com/quentin-fox/stripebug

Relevant App Code
// App.tsx

import React, {useState} from 'react';
import {Button, Modal, SafeAreaView, Text} from 'react-native';

import {CardField, StripeProvider} from '@stripe/stripe-react-native';

const publishableKey = '';
const merchantId = '';

function App(): JSX.Element {
  const [showCardField, setShowCardField] = useState(false);

  const [visible, setVisible] = useState(false);
  return (
    <SafeAreaView>
      <StripeProvider
        publishableKey={publishableKey}
        merchantIdentifier={merchantId}>
        <>
          <Text>Click Button to Show Card Field</Text>
          <Button title="Show" onPress={() => setShowCardField(true)} />

          {showCardField && <CardField style={{height: 50}} />}

          <Text>Click Button to Open Card Field in Modal</Text>
          <Button title="Show Modal" onPress={() => setVisible(true)} />

          <Modal visible={visible} animationType={'none'}>
            {showCardField && <CardField style={{height: 50}} />}
          </Modal>
        </>
      </StripeProvider>
    </SafeAreaView>
  );
}

export default App;

  1. Build App:
yarn install
yarn android
  1. In app UI, clicking the “Show” button will show the card field outside a modal correctly.
image
  1. Clicking the “Show Modal” button will crash the app.

Expected behavior Should render correctly + not crash the app.

Desktop (please complete the following information):

  • OS: Android
  • Stripe-React-Native Version 0.35.0
  • React-Native Version: 0.72.7

Additional context

Native stack trace:

01-23 14:38:29.316 18358 18358 E unknown:ReactModalHost: Creating new dialog from context: com.stripebug.MainActivity@36300e5@56819941
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: Exception in native call
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: java.lang.IllegalStateException: Cannot locate windowRecomposer; View androidx.compose.ui.platform.ComposeView{d7570fd V.E...... ......I. 0,0-0,0 #7f08014e app:id/icon} is not attached to a window
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at androidx.compose.ui.platform.WindowRecomposer_androidKt.getWindowRecomposer(WindowRecomposer.android.kt:295)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at androidx.compose.ui.platform.AbstractComposeView.resolveParentCompositionContext(ComposeView.android.kt:244)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at androidx.compose.ui.platform.AbstractComposeView.ensureCompositionCreated(ComposeView.android.kt:251)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at androidx.compose.ui.platform.AbstractComposeView.onMeasure(ComposeView.android.kt:288)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.View.measure(View.java:25833)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6980)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.View.measure(View.java:25833)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6980)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1204)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.widget.LinearLayout.onMeasure(LinearLayout.java:723)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.View.measure(View.java:25833)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6980)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.View.measure(View.java:25833)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.facebook.react.uimanager.NativeViewHierarchyManager.updateLayout(NativeViewHierarchyManager.java:189)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.facebook.react.uimanager.UIViewOperationQueue$UpdateLayoutOperation.execute(UIViewOperationQueue.java:169)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:915)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:1026)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.facebook.react.uimanager.UIViewOperationQueue.-$$Nest$mflushPendingBatches(Unknown Source:0)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1086)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:175)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:85)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1035)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.Choreographer.doCallbacks(Choreographer.java:845)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.Choreographer.doFrame(Choreographer.java:775)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.os.Handler.handleCallback(Handler.java:938)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.os.Handler.dispatchMessage(Handler.java:99)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.os.Looper.loopOnce(Looper.java:201)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.os.Looper.loop(Looper.java:288)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at android.app.ActivityThread.main(ActivityThread.java:7842)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at java.lang.reflect.Method.invoke(Native Method)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
01-23 14:38:29.366 18358 18358 E unknown:ReactNative: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
01-23 14:38:29.374 18358 18358 D AndroidRuntime: Shutting down VM
--------- beginning of crash
01-23 14:38:29.375 18358 18358 E AndroidRuntime: FATAL EXCEPTION: main
01-23 14:38:29.375 18358 18358 E AndroidRuntime: Process: com.stripebug, PID: 18358
01-23 14:38:29.375 18358 18358 E AndroidRuntime: java.lang.IllegalStateException: ViewTreeLifecycleOwner not found from android.widget.FrameLayout{919a043 V.E...... ......I. 0,0-0,0}
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer(WindowRecomposer.android.kt:352)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer$default(WindowRecomposer.android.kt:325)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at androidx.compose.ui.platform.WindowRecomposerFactory$Companion$LifecycleAware$1.createRecomposer(WindowRecomposer.android.kt:168)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at androidx.compose.ui.platform.WindowRecomposerPolicy.createAndInstallWindowRecomposer$ui_release(WindowRecomposer.android.kt:224)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at androidx.compose.ui.platform.WindowRecomposer_androidKt.getWindowRecomposer(WindowRecomposer.android.kt:300)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at androidx.compose.ui.platform.AbstractComposeView.resolveParentCompositionContext(ComposeView.android.kt:244)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at androidx.compose.ui.platform.AbstractComposeView.ensureCompositionCreated(ComposeView.android.kt:251)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at androidx.compose.ui.platform.AbstractComposeView.onAttachedToWindow(ComposeView.android.kt:283)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.View.dispatchAttachedToWindow(View.java:20812)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3490)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2675)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2179)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8787)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1037)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.Choreographer.doCallbacks(Choreographer.java:845)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.Choreographer.doFrame(Choreographer.java:780)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.os.Handler.handleCallback(Handler.java:938)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:99)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.os.Looper.loopOnce(Looper.java:201)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:288)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:7842)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
01-23 14:38:29.375 18358 18358 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

Related issue: #1584

About this issue

  • Original URL
  • State: open
  • Created 5 months ago
  • Reactions: 4
  • Comments: 17 (2 by maintainers)

Most upvoted comments

@quentin-fox

Are you facing difficulties and asking questions here? Is it appropriate to give a thumbs down to someone sincerely answering your questions? I believe it’s quite disrespectful as a developer.

I’ve encountered the same issue myself. Clearly, there is a conflict somewhere between the latest React Native Modal and this library. However, resolving this issue might take some time. Until someone comes up with a solution, we need to consider alternative approaches.

The method I suggested is extremely simple and useful. It involves using something other than React Native Modal, for example, there are alternatives even if it’s not React Navigation Modal, such as even a plain page. Don’t you think this is the best way until the problem is fundamentally resolved?

hy! @quentin-fox you can use an alternative for react native modal ,such like react navigation modal

hy! @quentin-fox card field never be open in modal in android its a bug , so use bottom sheet instead of modal.

Never would have guessed that being in a modal is what causes the crash especially since that is the first and only place i tried to render the CardField component.

@kamilms21 Since our team did not agree to downgrade the SDK, we decided to take the payment form out of the modal and change the UX a bit and it started working. You can refer to these two solutions: https://github.com/stripe/stripe-react-native/issues/1585#issuecomment-1895489406 or https://github.com/stripe/stripe-react-native/issues/1597#issuecomment-2022902427

@thanhcuong1990 @AnshIcode Thanks a lot for your support! I will try the solutions.