Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Build broken due to duplicate registered views for GooglePayButton and ApplePayButton #1225

Closed
walkerdb opened this issue Dec 3, 2022 · 17 comments · Fixed by #1233
Closed
Labels
reproduce Try and reproduce the issue

Comments

@walkerdb
Copy link
Contributor

walkerdb commented Dec 3, 2022

Describe the bug

We're trying out v0.22.0 to try the new createPlatformPayPaymentMethod flow. With the new version our metro builds fail with the following:

[Sat Dec 03 2022 14:23:46.213]  ERROR    Invariant Violation: Tried to register two views with the same name GooglePayButton

This seems to be due to the fact that @stripe/stripe-react-native is now internally calling

requireNativeComponent<any>('GooglePayButton')

in two different places, once in src/components/GooglePayButton.tsx and once in src/components/PlatformPayButton.tsx. If we comment out one of the requires (in our case src/components/GooglePayButton.tsx), the build works again*

* after resolving the GooglePayButton issue we saw the same thing for ApplePayButton, resolved in the same way.

To Reproduce

Run yarn start for your app after importing createPlatformPayPaymentMethod, then start up an ios simulator to start the metro dev-server compilation process.

Expected behavior

We can build our app with the new @stripe/stripe-react-native version.

Additional context

We're on react-native@63, which may be a factor if you're unable to reproduce on your own machine (further bumping to latest react-native for us was blocked by tipsi-stripe issues, which is why we're trying to migrate to @stripe/stripe-react-native).

@OooCleMooO
Copy link

+1

@charliecruzan-stripe
Copy link
Collaborator

Looking into this now! Will have a fix published most likely tomorrow, & thanks very much for trying out the new version

@charliecruzan-stripe
Copy link
Collaborator

So I'm only able to reproduce this when importing and rendering both components. Not ideal, but I wouldn't really recommend using both those APIs at once anyways. Let me know if there's a use case for that though.

If this is happening without rendering both components, then maybe this has to do with your RN version- I tested this down to RN 0.64 (which is the lowest RN version supported as of v0.8.0 of stripe-react-native).

@charliecruzan-stripe charliecruzan-stripe added the reproduce Try and reproduce the issue label Dec 5, 2022
@walkerdb
Copy link
Contributor Author

walkerdb commented Dec 5, 2022

hmmm we're not importing those components though. Here's an exhaustive list of imports that we're using:

import { isApplePaySupported, Token, CardField, createToken, createPlatformPayPaymentMethod, StripeProvider } from '@stripe/stripe-react-native';
import { CardFieldInput } from '@stripe/stripe-react-native/src/types';
import { CartSummaryItem } from '@stripe/stripe-react-native/src/types/PlatformPay';

I guess I wouldn't be surprised if the latter two imports had resolution side-effects that end up including something from the various Button components? But we currently need them since we need a type for the onCardChange callback param (CardFieldInput.Details) and for cartItem items.

@charliecruzan-stripe
Copy link
Collaborator

Hm, copy/pasting those imports still doesn't trigger the error for me on RN 64

@walkerdb
Copy link
Contributor Author

walkerdb commented Dec 5, 2022

hmm ok. We'll move forward with a patch-package approach then until we can update our react-native version.

If there's anyone else on < react-native 0.64, here's our patch file. If you use it you can't directly use ApplePayButton or GooglePayButton, but you should be using PlatformPayButton instead regardless.

diff --git a/node_modules/@stripe/stripe-react-native/src/components/ApplePayButton.tsx b/node_modules/@stripe/stripe-react-native/src/components/ApplePayButton.tsx
index 9be434f..34aec20 100644
--- a/node_modules/@stripe/stripe-react-native/src/components/ApplePayButton.tsx
+++ b/node_modules/@stripe/stripe-react-native/src/components/ApplePayButton.tsx
@@ -7,8 +7,8 @@ import {
   ViewStyle,
 } from 'react-native';
 
-const ApplePayButtonNative =
-  requireNativeComponent<ApplePayButtonComponent.NativeProps>('ApplePayButton');
+// const ApplePayButtonNative =
+//   requireNativeComponent<ApplePayButtonComponent.NativeProps>('ApplePayButton');
 
 /**
  *  Apple Pay Button Component Props
@@ -50,13 +50,7 @@ export function ApplePayButton({
   const style = useMemo(() => mapButtonStyle(buttonStyle), [buttonStyle]);
 
   return (
-    <ApplePayButtonNative
-      type={buttonType}
-      buttonStyle={style}
-      borderRadius={borderRadius}
-      onPressAction={onPress}
-      {...props}
-    />
+    null
   );
 }
 
diff --git a/node_modules/@stripe/stripe-react-native/src/components/GooglePayButton.tsx b/node_modules/@stripe/stripe-react-native/src/components/GooglePayButton.tsx
index e8d97ad..d8b1039 100644
--- a/node_modules/@stripe/stripe-react-native/src/components/GooglePayButton.tsx
+++ b/node_modules/@stripe/stripe-react-native/src/components/GooglePayButton.tsx
@@ -8,7 +8,7 @@ import {
   StyleSheet,
 } from 'react-native';
 
-const GooglePayButtonNative = requireNativeComponent<any>('GooglePayButton');
+// const GooglePayButtonNative = requireNativeComponent<any>('GooglePayButton');
 
 /**
  *  Google Pay Button Component Props
@@ -48,7 +48,7 @@ export function GooglePayButton({
       onPress={onPress}
       style={disabled ? styles.disabled : {}}
     >
-      <GooglePayButtonNative buttonType={type} {...props} />
+      {/*<GooglePayButtonNative buttonType={type} {...props} />*/}
     </TouchableOpacity>
   );
 }

@walkerdb
Copy link
Contributor Author

walkerdb commented Dec 5, 2022

thanks @charliecruzan-stripe for taking a look!

@charliecruzan-stripe
Copy link
Collaborator

Thanks for sharing that patch @walkerdb ! but if you are using rn < 64, you may run into this issue on Android: #919. Just wanted to note that and save you some googling

Let me know how the migration from tipsi-stripe and using the Platform Pay stuff works out, happy to chat anytime (my email is charliecruzan@stripe.com)

@walkerdb
Copy link
Contributor Author

walkerdb commented Dec 5, 2022

womp, thanks. tipsi-stripe was our react-native bump blocker, so I'll try updating to 0.64 to start and see what happens. Thanks for the heads up!

@walkerdb
Copy link
Contributor Author

walkerdb commented Dec 6, 2022

@charliecruzan-stripe hmm for the record, I still get the same error on react-native 0.64.4. Quite confused because I'm pretty sure the only reason it would happen would be if metro wasn't treeshaking and was instead actually resolving the GooglePayButton import somehow, even though we're not importing it, and no file in the stripe-react-native source imports from it other than the main src/index.tsx.

some env details if you end up having time to debug:

node: 16.15.0
yarn: 1.22.19
react-native: 0.64.4
metro: 0.64.0
metro-react-native-babel-preset: 0.66.2
@babel/core (and other various babels): 7.18.13
typescript: 4.8.4

Current full import list, spread throughout a few files:

import {
  CardField,
  createPlatformPayPaymentMethod,
  createToken,
  isPlatformPaySupported,
  PlatformPay,
  StripeProvider,
  Token,
} from '@stripe/stripe-react-native';

Start command: yarn react-native start --config './react-native.config.js'

Some of our build config:

// react-native.config.js
module.exports = {
  transformer: {
    // config to allow sentry breadcrumbs to show real names
    minifierConfig: {
      keep_classnames: true,
      keep_fnames: true,
      mangle: {
        keep_classnames: true,
        keep_fnames: true,
      },
    },
  },
};
// babel.config.js
module.exports = function babel(api) {
  api.cache(false);

  const presets = ['module:metro-react-native-babel-preset'];

  const plugins = [
    '@babel/plugin-transform-flow-strip-types',
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    '@babel/plugin-proposal-class-properties',
    '@babel/plugin-transform-react-jsx-source',
    'babel-plugin-styled-components',
    '@fullstory/react-native',
    [
      'babel-plugin-module-resolver',
      {
        extensions: [
          '.ios.js',
          '.ios.ts',
          '.ios.tsx',
          '.android.js',
          '.android.ts',
          '.android.tsx',
          '.native.js',
          '.native.ts',
          '.native.tsx',
          '.js',
          '.ts',
          '.tsx',
          '.json',
        ],
        alias: {
          '~native': '.',
          '~shared': '../../libs/shared',
          '~web': '../../apps/web/src',
          react: './node_modules/react',
          'react-dom': './node_modules/react-dom',
        },
      },
    ],
  ];

  return {
    presets,
    plugins,
    env: {
      production: {
        plugins: ['transform-remove-console'],
      },
    },
  };
};
// tsconfig.json
{
  "exclude": ["node_modules", "babel.config.js", "metro.config.js", "react-native.config.js", "jest.config.js"],
  "compilerOptions": {
    "target": "esnext",
    "module": "commonjs",
    "lib": ["es2019"],
    "allowJs": true,
    "jsx": "react-native",
    "noEmit": true,
    "isolatedModules": true,
    "strict": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "baseUrl": ".",
    "paths": {
      "~web/*": ["../web/src/*"],
      "~native/*": ["./*"],
      "~shared/*": ["../../libs/shared/*"],
      "@tanstack/react-query": ["./node_modules/@tanstack/react-query"],
      "react-redux": ["./node_modules/react-redux"]
    },
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

@charliecruzan-stripe
Copy link
Collaborator

Let me take a look and see if i can reproduce that @walkerdb , thanks for all the info 🙏

@sanny-naked
Copy link

I was experiencing this error from simply wrapping a View with StripeProvider.

"@stripe/stripe-react-native": "^0.22.0",
"react-native": "0.69.6",

@walkerdb's patch has made it go away. Thank you.

@ravindra-encoresky
Copy link

ravindra-encoresky commented Dec 7, 2022

I'm on react-native": 0.64.0 still I'm getting it.
I'm trying to migrate from tipsi-stripe.
the error is : invariant Violation: Tried to register two views with the same name GooglePayButton

with patch working fine

@charliecruzan-stripe
Copy link
Collaborator

hey everyone- @walkerdb I was able to reproduce this using your react-native.config.js file. If you run your project without the --config './react-native.config.js', do you get the error anymore?

@charliecruzan-stripe
Copy link
Collaborator

Regardless- will have a fix for this landed soon :)

@charliecruzan-stripe
Copy link
Collaborator

Fixed in Fixed in v0.22.1 ✅

@walkerdb
Copy link
Contributor Author

walkerdb commented Dec 8, 2022

confirmed thank you!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reproduce Try and reproduce the issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants