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

crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supporte #514

Closed
chinomnsoawazie opened this issue Sep 3, 2020 · 24 comments · Fixed by #518

Comments

@chinomnsoawazie
Copy link

chinomnsoawazie commented Sep 3, 2020

Just got this surprising error after using uuid for so long

Environment
"react-native": "0.63.2"
"react-native-get-random-values": "^1.4.0"
"uuid": "^8.3.0"

What was tried
I get this error when const id = uuidv4() runs. I added "react-native-get-random-values" as suggested, but with yarn and imported it this way;

import React, {useState} from 'react';
import 'react-native-get-random-values';
import {v4 as uuidv4} from 'uuid';
import RNPickerSelect from 'react-native-picker-select';

I am still getting the same error. Have to figure out other ways to generate a random ID then.

[Clear, concise description of the problem]

How to reproduce

  1. Install the uuid and react-native-get-random-values
  2. try running a component with this const id = uuidv4()

Expected behavior

Should generate random ids

Runtime

  • OS: macOS
  • Runtime: react-native
  • Runtime Version: 0.63.2
@puzpuzpuz
Copy link
Contributor

This seems to be the same issue as #375

@LinusU
Copy link
Member

LinusU commented Sep 4, 2020

Are you using Expo? In that case you need to upgrade to SDK 39 (which isn't out yet 🙈)

Are you developing for iOS? Can you try run npx pod-install in your project and see if that fixes the problem.

@chinomnsoawazie
Copy link
Author

Are you using Expo? In that case you need to upgrade to SDK 39 (which isn't out yet 🙈)

Are you developing for iOS? Can you try run npx pod-install in your project and see if that fixes the problem.

No I am not. I am developing for iOS, and have ran a number of pod install within the iOS folder after adding the package at app level without the problem going away. I already had pods for the project installed and generated.

I ended up going with uuid-random: ^1.3.2. Got the job done, and I see that package is picking up steam judging by the weekly download figures.... possibly by people who can't deal no more(?)🤔

@chinomnsoawazie
Copy link
Author

This seems to be the same issue as #375

Not quite... I am not using Expo on this project, issue #375 involves Expo platform. I would hazard a guess that a fix which works for the Expo platform will work on native too.

@ctavan
Copy link
Member

ctavan commented Sep 9, 2020

@chinomnsoawazie this is surprising, it should work with regular react-native in the way you show above. Would you mind comparing your setup with https://github.com/ctavan/uuid-example-react-native which also uses react-native 0.63.2 and works flawlessly?

Please beware that uuid-random is using Math.random() as a fallback when no cryptographically secure random number generator (CSPRNG) is available, which is the case in react-native without polyfill. You could equally just stick to uuid@3.4.0 which did exactly the same. It was a deliberate decision to remove support for flawed random number generators with uuid@7.0.0. If you are interested in the details of why using Math.random() to generate UUIDs is a bad idea, feel free to read the discussion in #173.

@chinomnsoawazie
Copy link
Author

@chinomnsoawazie this is surprising, it should work with regular react-native in the way you show above. Would you mind comparing your setup with https://github.com/ctavan/uuid-example-react-native which also uses react-native 0.63.2 and works flawlessly?

Please beware that uuid-random is using Math.random() as a fallback when no cryptographically secure random number generator (CSPRNG) is available, which is the case in react-native without polyfill. You could equally just stick to uuid@3.4.0 which did exactly the same. It was a deliberate decision to remove support for flawed random number generators with uuid@7.0.0. If you are interested in the details of why using Math.random() to generate UUIDs is a bad idea, feel free to read the discussion in #173.

Just tried your suggested configuration this way...

  • I did yarn install uuid (I had removed it from my application!)
  • I did cd ios && pod install && cd ..
  • I added import 'react-native-get-random-values; to my index.js as you suggested (previously, I had imported this in the same component I needed it in)
  • I did import {v4 as uuidv4} from 'uuid' in the component I needed the ids.
  • I now had my const id = uuidv4(); in the component I needed it.
  • Then I rebuilt my app with Xcode and got it re-installed and running on my phone.
  • ...And the error, which is the title of this issue, came back

So, that suggestion did not work. I did not expect it to work though because I was wondering what difference it would make placing import 'react-native-get-random-values; in the index.js as opposed to the component it is needed in, especially, as the 'App' is not wrapped by it at that point.

@ctavan
Copy link
Member

ctavan commented Sep 11, 2020

Hmm, does the same error appear when you clone https://github.com/ctavan/uuid-example-react-native and run:

yarn
npx pod-install
yarn run ios

@chinomnsoawazie
Copy link
Author

chinomnsoawazie commented Sep 11, 2020

Hmm, does the same error appear when you clone https://github.com/ctavan/uuid-example-react-native and run:

yarn
npx pod-install
yarn run ios

I am not exactly sure why you need me to clone your repo for this issue; I have taken a look at your package.json and we have the same non-expo environment (package.json dependencies and their versions with respect to this issue), this issue is also affecting those using Expo as issue #375 highlights. Your second suggestion is no different from the first one you made, which I already tried. Maybe if you added more npm packages to your app to create some realistic solution (so that way, there are more interactions between packages), you'll be able to replicate the error which clearly exists. Refer to same issue but on an Expo environment as highlighted by issue #375

@ctavan
Copy link
Member

ctavan commented Sep 11, 2020

The expo-related issue from #375 is clearly understood and reproducible. If you are seeing the same error on a non-expo react native app it must be a different issue, as https://github.com/ctavan/uuid-example-react-native proves that it is well possible to use uuid in combination with react-native-get-random-values on plain react native apps.

Please provide a Minimal Reproducible Example, otherwise I simply don't have enough information about your specific setup in order to further debug this.

@chinomnsoawazie
Copy link
Author

The expo-related issue from #375 is clearly understood and reproducible. If you are seeing the same error on a non-expo react native app it must be a different issue, as https://github.com/ctavan/uuid-example-react-native proves that it is well possible to use uuid in combination with react-native-get-random-values on plain react native apps.

Please provide a Minimal Reproducible Example, otherwise I simply don't have enough information about your specific setup in order to further debug this.

Here is the repo for the ongoing demonstration project that this situation happens. Feel free to use it for debugging purposes. Hopefully that helps as all I really wanted to do was raise this issue with hopes of drawing your attention to it. I really wish I had the time resources to invest more on this. Regards.

https://github.com/chinomnsoawazie/dogstagram-frontweb-mobile

ctavan added a commit to ctavan/dogstagram-frontweb-mobile that referenced this issue Sep 11, 2020
Import react-native-get-random-values _before_ importing App (which in
turn imports uuid). As documented in
https://github.com/uuidjs/uuid#react-native

Fixes uuidjs/uuid#514
@ctavan
Copy link
Member

ctavan commented Sep 11, 2020

As mentioned in the documentation and as shown in the working example react-native-get-random-values must be imported before uuid is imported (or, in the case of your app, before App.js is imported, just like it's done here).

I've submitted a PR to your sample repo which hopefully fixes the issue https://github.com/chinomnsoawazie/dogstagram-frontweb-mobile/pull/1 (I couldn't properly test it because I couldn't get past the login screen, I was able to produce a uuid on the login screen though using this commit: ctavan/dogstagram-frontweb-mobile@efac2b8).

@ctavan ctavan closed this as completed Sep 11, 2020
@chinomnsoawazie
Copy link
Author

chinomnsoawazie commented Sep 12, 2020

As mentioned in the documentation and as shown in the working example react-native-get-random-values must be imported before uuid is imported (or, in the case of your app, before App.js is imported, just like it's done here).

I've submitted a PR to your sample repo which hopefully fixes the issue chinomnsoawazie/dogstagram-frontweb-mobile#1 (I couldn't properly test it because I couldn't get past the login screen, I was able to produce a uuid on the login screen though using this commit: ctavan/dogstagram-frontweb-mobile@efac2b8).

I think the most important line in your last comment is "react-native-get-random-values must be imported before uuid is imported (or, in the case of your app, before App.js)". The documentation as it is right now is not very clear on that, especially, the part that says....

"getRandomValues() not supported"
This error occurs in environments where the standard crypto.getRandomValues() API is not supported. This issue can be resolved by adding an appropriate polyfill:

React Native

  1. Install react-native-get-random-values
  2. Import it before uuid:

import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';

Cursory reading of that makes one think that will work in the component where uuid will be used, but it doesn't. More clarity on where, and in what order would help, eg specifically stating this has to be done in index.js and it has to be imported before App.js. Also highlighting the fact that in fixing this issue through importing react-native-get-random-values in index.js, it needs to be imported before the App.js component might help. In your example, you might also want to add a comment to reflect that specific situation. I know it is on the main page, but someone looking for a quick fix might miss that specific requirement. I have submitted an issue to that particular page in your example repo.

@ctavan
Copy link
Member

ctavan commented Sep 12, 2020

One reason why importing it directly before uuid may not work is if uuid also comes as a transitive dependency of some other dependency that has been imported even earlier in the import chain.

This is indeed something I didn't really consider so far. I will update the documentation to be a bit more clear on that.

@broofa
Copy link
Member

broofa commented Sep 12, 2020

Is this something react-native-get-random-values could detect and warn / throw about?

@ctavan
Copy link
Member

ctavan commented Sep 12, 2020

I don't see how? The problem here really is that we get the reference to crypto.getRandomValues() on module load time:

uuid/src/rng-browser.js

Lines 5 to 25 in ac1b3af

// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
// find the complete implementation of crypto (msCrypto) on IE11.
const getRandomValues =
(typeof crypto !== 'undefined' &&
crypto.getRandomValues &&
crypto.getRandomValues.bind(crypto)) ||
(typeof msCrypto !== 'undefined' &&
typeof msCrypto.getRandomValues === 'function' &&
msCrypto.getRandomValues.bind(msCrypto));
const rnds8 = new Uint8Array(16);
export default function rng() {
if (!getRandomValues) {
throw new Error(
'crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'
);
}
return getRandomValues(rnds8);
}

This is where the import order dependency comes from. We could move this statement into the rng() function body. I don't expect a performance hit here and since we currently also only throw upon the first invocation of rng() we should get the same result.

Another idea would be to actually throw on load time. WDYT?

@yaltha
Copy link

yaltha commented Mar 26, 2021

As mentioned in the documentation and as shown in the working example react-native-get-random-values must be imported before uuid is imported (or, in the case of your app, before App.js is imported, just like it's done here).
I've submitted a PR to your sample repo which hopefully fixes the issue chinomnsoawazie/dogstagram-frontweb-mobile#1 (I couldn't properly test it because I couldn't get past the login screen, I was able to produce a uuid on the login screen though using this commit: ctavan/dogstagram-frontweb-mobile@efac2b8).

I think the most important line in your last comment is "react-native-get-random-values must be imported before uuid is imported (or, in the case of your app, before App.js)". The documentation as it is right now is not very clear on that, especially, the part that says....

"getRandomValues() not supported"
This error occurs in environments where the standard crypto.getRandomValues() API is not supported. This issue can be resolved by adding an appropriate polyfill:

React Native

  1. Install react-native-get-random-values
  2. Import it before uuid:

import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';

Cursory reading of that makes one think that will work in the component where uuid will be used, but it doesn't. More clarity on where, and in what order would help, eg specifically stating this has to be done in index.js and it has to be imported before App.js. Also highlighting the fact that in fixing this issue through importing react-native-get-random-values in index.js, it needs to be imported before the App.js component might help. In your example, you might also want to add a comment to reflect that specific situation. I know it is on the main page, but someone looking for a quick fix might miss that specific requirement. I have submitted an issue to that particular page in your example repo.

This solution works on me

  1. Install react-native-get-random-values
  2. Import it before uuid:

import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';

@piranna
Copy link
Member

piranna commented Mar 26, 2021

I have implemented a polyfill for randomUUID() Node.js and upcoming WICG standard at https://github.com/uuidjs/randomUUID :-)

@yaltha
Copy link

yaltha commented Mar 28, 2021

I have implemented a polyfill for randomUUID() Node.js and upcoming WICG standard at https://github.com/uuidjs/randomUUID :-)

Awesome, Thank you

@piranna
Copy link
Member

piranna commented Mar 29, 2021

Awesome, Thank you

You are welcome :-)

@here-nerd
Copy link

here-nerd commented Apr 13, 2021

I run into the same issue when running uuidv4() in a LiquidPlayer, which is a V8 based JS VM, just like NodeJS. I wonder that the error message 'crypto.getRandomValues() not supported' might be misleading in this case because crypto.getRandomValues() should be there. Would it help to add these lines in rng-browser.js?

// Native crypto import via require (NodeJS)
if (!crypto && typeof require === 'function') {
    try {
        crypto = require('crypto');
    } catch (err) {}
}

@broofa
Copy link
Member

broofa commented Apr 14, 2021

LiquidPlayer, which is a V8 based JS VM, just like NodeJS... in rng-browser.js?

@here-nerd : I'm not familiar with LiquidPlayer but it looks like it's a Node.js runtime (variant). As such it shouldn't be using the package.json#browser aliases. I.e. it should be loading rng.js, not rng-browser.js. And rng.js already does require('crypto').

Maybe check to make sure your packager is bundling for the correct target environment. For example.

@enricop89
Copy link

@chinomnsoawazie Your method works if you are importing react-native-get-random-values in the your App but what happens when are working on a library that has uuid as a dependency? My question is related to #570 (comment). I don't see a way to make it work

@ddeerdevil
Copy link

Today i use rollup to build and run into the same issue.
After a long time of troubleshooting, i find words in https://www.npmjs.com/package/@rollup/plugin-node-resolve
this plugin looks for the ['default', 'module', 'import'] conditions when resolving imports.

Then, i check the uuid's package.json, find that default": "./dist/esm-browser/index.js in exports field.
Finally i set @rollup/plugin-node-resolve 's exportConditions property to ['node'], solve the problem.😄

@nikhilnxvverma1
Copy link

Just wanted to add that this issue is fixed in jest v29. But I guess your main environment still needs to run in localhost or https

EosFoundry added a commit to EosFoundry/makeshift-ctrl that referenced this issue Sep 23, 2023
move uuid to external module to fix uuidjs/uuid#514
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.