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

[React Native] API calls don't work when using chrome debugger #929

Closed
Amplifiyer opened this issue Feb 15, 2020 · 4 comments
Closed

[React Native] API calls don't work when using chrome debugger #929

Amplifiyer opened this issue Feb 15, 2020 · 4 comments
Assignees
Labels
bug This issue is a bug. rc-blocker

Comments

@Amplifiyer
Copy link
Contributor

Amplifiyer commented Feb 15, 2020

Describe the bug
When chrome debugger is attached to the ios simulator (or Android emulator), calls to AWS services do not finish for a long time. Making another service call triggers previous call to finish. For instance let's say the app logs Sending Request before making the request and Request succeeded once the request completes, we only see Sending Request but not Request succeeded until other API call is made.

SDK version number
Latest alpha client versions as of now.

Is the issue in the browser/Node.js?
React Native

Details of the browser/Node.js version
I'm using React Native 0.61.5 and RN CLI to create the app.

To Reproduce (observed behavior)

  • Create a RN app using React Native CLI
  • Add a function that calls S3:PubObjects API and add console.log before and after the call.
  • Start Remote debugging in the simulator/emulator and open/attach chrome debugger.
  • Call the function and observe that only first log gets printed.
  • Call the function again and you'll see the response from the first call but again the response from the second call is missing.

It doesn't happen when not using chrome debugger.

Expected behavior
There shouldn't be any issues using RN with chrome debugger.

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem here.

@Amplifiyer Amplifiyer added the bug This issue is a bug. label Feb 15, 2020
@AllanZhengYP AllanZhengYP self-assigned this Feb 17, 2020
@AllanZhengYP
Copy link
Contributor

AllanZhengYP commented Feb 28, 2020

This issue is reproducable in master branch of /~https://github.com/aws-samples/aws-sdk-js-tests. I tried look into where the RN debugger gets deactivated, and I find it's around returning the promise from Sha256 functions, from @aws-crypto/sha256-browser package. Especially when we try to calculate the hash using crypto.subtle class.

When debugger steps into:

      return util_locate_window_1.locateWindow().crypto.subtle.digest(constants_1.SHA_256_HASH, _this.toHash).then(function (data) {
        return new Uint8Array(data);
      });
    };

The digest() is called but the RN event bridge got flushed afterwards, hence the debugger deactivates and returned promise never resolves in debugger.

The root cause is unknown, but I find I can workaround it by forcing @aws-crypto/sha256-browser package to use raw JS implementation instead of the Crypto.subtle in window. Currently there's no way to programably force the package to use raw JS implementation. I will reach out to the package owner to figure out whether we can progress with this solution.

@AllanZhengYP
Copy link
Contributor

AllanZhengYP commented Mar 3, 2020

After more investigation, the cause is more clear: the crypto package uses window.crypto hasher provider in RN debug mode, whereas it uses pure JS implementation when debug mode is off.

This behavior can be validated by adding inline console log in @aws-crypto/sha256-browser dependency's constructor:

function Sha256(secret) {
        if (supports_web_crypto_1.supportsWebCrypto(util_locate_window_1.locateWindow())) {
            console.log('WebCrypto')
            this.hash = new webCryptoSha256_1.Sha256(secret);
        }
        else if (ie11_detection_1.isMsWindow(util_locate_window_1.locateWindow())) {
            console.log('MSCrypto')
            this.hash = new ie11Sha256_1.Sha256(secret);
        }
        else {
            console.log('PUREJS')
            this.hash = new sha256_js_1.Sha256(secret);
        }
    }

In debug mode, console log prints:

WebCrypto
WebCrypto
...

In non-debug mode, console log prints:

PUREJS
PUREJS
...

The same behavior is also confirmed in react-native-cli

Conclusion:
React Native does not support WebCrypto and the Prod env does not have a window.crypto.subtle object. But when the app is in debug mode, the JS is exectued in Chrome, the window.crypto.subtle is available. However, the functure only returns a promise that never resolves. The reason why event like touching or scrolling in RN makes the app generating correct hash in debug mode is still unclear.

Hypothetically, Expo may fall back to /~https://github.com/expo/expo/tree/master/packages/expo-crypto but this native package requires event loop moves over from JS side to native side. So user s need to touch screento make event loop progress.

I'm working with the crypto package owner to get this resolved on that side

@AllanZhengYP
Copy link
Contributor

A fix that makes RN bundles using pure JS SHA256 implementation is released in 1.0.0-alpha.27. I have validated locally. Please ask for reopen if the same issue persists.

@lock
Copy link

lock bot commented Mar 27, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

@lock lock bot locked as resolved and limited conversation to collaborators Mar 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug This issue is a bug. rc-blocker
Projects
None yet
Development

No branches or pull requests

2 participants