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

Recently installed in an Expo 37/RN app, getting TypeError: null is not an object (evaluating 'RNGetRandomValues.getRandomBase64') #207

Closed
PaulHaze opened this issue Apr 9, 2020 · 57 comments · Fixed by #231

Comments

@PaulHaze
Copy link

PaulHaze commented Apr 9, 2020

As stated in the title, recently installed it into an Expo 37 app as I was all of a sudden getting errors using uuid.V4. Followed the instructions and made sure I installed and imported 'react-native-get-random-values' (both at the top of my index.js entry point of the app, and every where else I used nanoid.

On starting the app I get this error:

TypeError: null is not an object (evaluating 'RNGetRandomValues.getRandomBase64')

getRandomValues
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:126457:35
nanoid
    index.browser.js:80:2
arr.map$argument_0
    grape-varietals.js:10:18
map
    [native code]:0
<global>
    grape-varietals.js:9:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:126380:39
loadModuleImplementation
    require.js:322:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:126309:36
loadModuleImplementation
    require.js:322:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:126059:61
loadModuleImplementation
    require.js:322:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:126024:53
loadModuleImplementation
    require.js:322:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:124002:50
loadModuleImplementation
    require.js:322:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:123965:50
loadModuleImplementation
    require.js:322:6
<global>
    AppEntry.js:3
loadModuleImplementation
    require.js:322:6
guardedLoadModule
    require.js:201:45
global code
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:165136:4

rng
    rng-browser.js:16:7
v4
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:126911:63
arr.map$argument_0
    grape-varietals.js:9:18
map
    [native code]:0
<global>
    grape-varietals.js:8:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:126376:39
loadModuleImplementation
    require.js:322:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:126307:36
loadModuleImplementation
    require.js:322:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:126057:61
loadModuleImplementation
    require.js:322:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:126022:53
loadModuleImplementation
    require.js:322:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:124000:50
loadModuleImplementation
    require.js:322:6
<unknown>
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:123965:50
loadModuleImplementation
    require.js:322:6
<global>
    AppEntry.js:3
loadModuleImplementation
    require.js:322:6
guardedLoadModule
    require.js:201:45
global code
    AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:165602:4

I am implementing in my code like this:

import 'react-native-get-random-values';
import { nanoid } from 'nanoid';
// other code
const createVarietalArray = (arr, color, common) => {
  return arr.map(v => new Varietal(nanoid(), color, v, false, common));
};

const COMMON_RED = createVarietalArray(redVarietals.common, 'red', true);

Any idea what might be causing this?

@ai
Copy link
Owner

ai commented Apr 9, 2020

Thanks for the report. I will be able to look only tomorrow because I am going to sleep.

In a quick look, you have some problem with react-native-get-random-values. Try to report the issue also to them.

@PaulHaze
Copy link
Author

PaulHaze commented Apr 9, 2020

My mistake sorry, on further investigation I see this library only works in a bare RN project, and I am building this with Expo, therefore I'm pretty sure that is where the issue is.

So you can probably ignore this.... sorry about that!

@ai
Copy link
Owner

ai commented Apr 9, 2020

It was still good that you opened this issue. As I mentioned in my article every issue should change code or docs to avoid the same mistakes in the future.

Let’s improve docs. What is the solution for Expo?

@PaulHaze
Copy link
Author

Well its strange, I have two projects, one that uses uuidV4 which is working fine, and I have pretty much cloned that one (but removed a native-base UI dependency that I was barely using) and now that one is throwing errors along these lines: uuidjs/uuid#375

The strange thing is I have compared the package.json of each package and the only difference is is Expo 37.0.3 as opposed to 37.0.0. (the working one is the lower version number).

Searching for a solution to this led me to your package which looked like a much better solution, but as I have found out only works without expo :(.

Expo solution at the moment is to use their 'expo-random' package, but I have tried that and have already got clashes with lists of around 200 so its not really a solution.....

@PaulHaze
Copy link
Author

p.s. I see you have a keen interest in space. Same here! Not sure if this is the right place but I make and mix a lot of 'space-inspired' music. Have a listen here if you like:
https://soundcloud.com/deejay-hazy/sets/floating-in-space
And if this is not really github eitiquette then let me know and I will delete this message....

@LinusU
Copy link

LinusU commented Apr 10, 2020

This is the relevant issue for Expo: expo/expo#7209

Please give your thumbs up so that the developers of Expo understand that this is a much desired feature, I've offered to do all the work and submit a PR with the implementation!

Expo solution at the moment is to use their 'expo-random' package

Unfortunately, the expo-random package is asynchronous so it cannot be used to polyfill crypto.getRandomValues 😭

@ai
Copy link
Owner

ai commented Apr 10, 2020

I can add special version of nanoid/async for React Native, which will use and require expo.

@code-by
Copy link

code-by commented Apr 13, 2020

same on Expo 36

@GollyJer
Copy link

So frustrating. Was excited to have a synchronous solution until my Expo app complete broke after the upgrade to 3.0. 😕
Back to async sadness of 2.x for now.

@ai
Copy link
Owner

ai commented May 12, 2020

I will try to find time at weekend to make nanoid/async compatible with expo again

@ai
Copy link
Owner

ai commented May 12, 2020

I added expo support to the master 3ac74c1

I will release it if somebody will test that it works:

npm uninstall nanoid
npm install nanoid@ai/nanoid

@GollyJer
Copy link

GollyJer commented May 13, 2020

Hi @ai
So I'm clear what to test and expect...

Should I change my imports.

- import nanoid from 'nanoid/async'
+ import { nanoid } from 'nanoid'

and expect to use synchronous calls?
or

- import nanoid from 'nanoid/async'
+ import { nanoid } from 'nanoid/async'

and continue to use async?

Thanks!

@ai
Copy link
Owner

ai commented May 13, 2020

@GollyJer you should use async version (but use named export) with expo:

- import nanoid from 'nanoid/async'
+ import { nanoid } from 'nanoid/async'

@GollyJer
Copy link

Cool. That was my guess but wanted to be sure.

I will be able to test in app by Thursday at the latest. Thanks.

@1ike
Copy link

1ike commented May 15, 2020

@ai

npm install nanoid@ai/nanoid

and
import { nanoid } from 'nanoid/async'

It's working (Expo 36). Can't check random but at least it gives ids. It also need 'expo-random' as dependency. And 'react-native-get-random-values' as well.
Without these dependencies there are only chance use import { nanoid } from 'nanoid/non-secure' that offer predictable and less unique ids.

UPDATE.
It looks like 'react-native-get-random-values' is a needless a bit. Because nanoid gives id but later appears error

[Unhandled promise rejection: TypeError: null is not an object (evaluating 'RNGe
tRandomValues.getRandomBase64')]

that intrinsic to 'react-native-get-random-values'.

But without 'react-native-get-random-values' there are error at start
Error: React Native does not have a built-in secure random generator.
Screenshot_1589579316

I think more suitable will be error like this when absent 'expo-random' (which replaced 'react-native-get-random-values' if I understand right):
Screenshot_1589579316_2

@ai
Copy link
Owner

ai commented May 16, 2020

Great. I will try to release new version on this weekend.

@ai
Copy link
Owner

ai commented May 16, 2020

Requiring react-native-get-random-values for nanoid/async was a bug. I fixed it in f6cad02

I added docs for Expo a3518e9 and released Expo support in 3.1.8.

@ai ai closed this as completed May 16, 2020
@1ike
Copy link

1ike commented May 16, 2020

Thanks a lot. f6cad02 realy fixed error with react-native-get-random-values.

But I still need install package via npm install nanoid@ai/nanoid. Is it ok? If it's ok then will be usefull to add such info to Readme.

And for the change in error message - I didn't mean to change existed (may be mention about react-native-get-random-values will help with pure RN without Expo). I meant that old message must not be shown with Expo (and it was gone with f6cad02) and add new message if it possible to specify case with using Expo.
In its current form the message is useless because now (and before) absent of expo-random cause error during bundling:
Unable to resolve "expo-random" from "node_modules\nanoid\async\random\index.native.js" . That error and exsisted mention about expo-random in Readme is enough for me.

@ai
Copy link
Owner

ai commented May 16, 2020

But I still need install package via npm install nanoid@ai/nanoid. Is it ok?

Nope. You can use nanoid from npm. Just double-check that you use the latest version.

Unable to resolve "expo-random" from "node_modules\nanoid\async\random\index.native.js"

Unfortunately, I do not knwo how to import this error message. ES imports (we support them by dual-publish supports only global import. We can do try { require() } catch {} anymore.

@1ike
Copy link

1ike commented May 16, 2020

Nope. You can use nanoid from npm. Just double-check that you use the latest version.

I can't. That is srange but 1.3.8 does not work for me. Only nanoid@ai/nanoid. Tried to clear yarn cache but it did not help.

Unfortunately, I do not knwo how to import this error message.

I offer forget about it for a while. As I wrote anyone can figure out that he need expo-random via Unable to resolve "expo-random" error and Readme.
Only drawbacks are lack of proposal use non-secure and uselessness of corrected error code.

@ai
Copy link
Owner

ai commented May 16, 2020

I can't. That is srange but 1.3.8 does not work for me

What exactly do you see with 3.1.8?

@1ike
Copy link

1ike commented May 16, 2020

What exactly do you see with 3.1.8?

Nothing. In literal sense. No errors just only first console.log in code beneath, second disappear like in black hole:

  async addJob(name, args, options) {
    console.log('id!');
    const id = await uuid();
    console.log('id = ', id);
    .....

@ai
Copy link
Owner

ai commented May 17, 2020

@1ike show the result of:

  async addJob(name, args, options) {
    console.log('id!');
    const promise = uuid();
    console.log('promise = ', promise);

@1ike
Copy link

1ike commented May 17, 2020

First console.log at 4th line.

Finished building JavaScript bundle in 5066ms.
[sentry-expo] Disabled Sentry in development. Note you can set Sentry.init({ ena
bleInExpoDevelopment: true });
id!
Running application on Android SDK built for x86.

Warning: componentWillMount has been renamed, and is not recommended for use. Se
e https://fb.me/react-async-component-lifecycle-hooks for details.

* Move code with side effects to componentDidMount, and set initial state in the
 constructor.
* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warnin
g in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename
all deprecated lifecycles to their new names, you can run `npx react-codemod ren
ame-unsafe-lifecycles` in your project source folder.

Please update the following components: Icon
- node_modules\react-native\Libraries\YellowBox\YellowBox.js:71:8 in console.war
n
- node_modules\expo\build\environment\muteWarnings.fx.js:18:23 in warn
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:5864:19 in printWarning
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:5892:25 in lowPriorityWarning
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:6116:8 in ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:20377:6 in flushRenderPhaseStrictModeWarningsInDEV
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:19606:41 in commitRootImpl
* [native code]:null in commitRootImpl
- node_modules\scheduler\cjs\scheduler.development.js:643:23 in unstable_runWith
Priority
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:19590:4 in commitRoot
* [native code]:null in commitRoot
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:18709:28 in runRootCallback
* [native code]:null in runRootCallback
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:5642:32 in runWithPriority$argument_1
- node_modules\scheduler\cjs\scheduler.development.js:643:23 in unstable_runWith
Priority
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:5638:22 in flushSyncCallbackQueueImpl
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:5627:28 in flushSyncCallbackQueue
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:18556:30 in scheduleUpdateOnFiber
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:21822:15 in scheduleRootUpdate
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRender
er-dev.js:23042:20 in ReactNativeRenderer.render
- node_modules\react-native\Libraries\ReactNative\renderApplication.js:52:52 in
renderApplication
- node_modules\react-native\Libraries\ReactNative\AppRegistry.js:116:10 in runna
bles.appKey.run
- node_modules\react-native\Libraries\ReactNative\AppRegistry.js:197:26 in runAp
plication
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:436:47 in __
callFunction
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:111:26 in __
guard$argument_0
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:384:10 in __
guard
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:110:17 in __
guard$argument_0
* [native code]:null in callFunctionReturnFlushedQueue

getAllJobs() =  Array []
job =  undefined
.....

Look like async addJob function executed too long, I never could wait till it reject or resolve during of 5 minutes at least.

With "nanoid": "ai/nanoid", it's ok:

Finished building JavaScript bundle in 4180ms.
[sentry-expo] Disabled Sentry in development. Note you can set Sentry.init({ ena
bleInExpoDevelopment: true });
id!
Running application on Android SDK built for x86.
id =  7woFbgfe_UvMCWT4xFY3T

Warning: componentWillMount has been renamed, and is not recommended for use. Se
e https://fb.me/react-async-component-lifecycle-hooks for details.

* Move code with side effects to componentDidMount, and set initial state in the
 constructor.
.......

@GollyJer
Copy link

I followed the instructions for 3.1.8 and Expo but get this error.

[Unhandled promise rejection: ReferenceError: Can't find variable: crypto]
- node_modules\nanoid\async\index.browser.js:44:2 in nanoid

Using expo 37.

@ai
Copy link
Owner

ai commented May 17, 2020

@GollyJer can you try import { nanoid } from 'nanoid/async/index.native.js'?

What builder do you use? The default Metro?

@ai ai reopened this May 17, 2020
@ai
Copy link
Owner

ai commented May 17, 2020

@1ike can you show me the result of:

import { getRandomBytesAsync } from 'expo-random'

console.log(getRandomBytesAsync)
console.log(getRandomBytesAsync(5))
getRandomBytesAsync(5).then(bytes => console.log(bytes))

@GollyJer
Copy link

GollyJer commented May 17, 2020

@GollyJer can you try import { nanoid } from 'nanoid/async/index.native.js'?

There's export at this location.

What builder do you use? The default Metro?

Yes. The default Metro.

@1ike
Copy link

1ike commented May 17, 2020

Finished building JavaScript bundle in 5838ms.
[sentry-expo] Disabled Sentry in development. Note you can set Sentry.init({ ena
bleInExpoDevelopment: true });
[Function getRandomBytesAsync]
Promise {
  "_40": 0,
  "_55": null,
  "_65": 0,
  "_72": null,
}
id!
Running application on Android SDK built for x86.
Uint8Array [
  153,
  22,
  147,
  121,
  38,
]

@ai
Copy link
Owner

ai commented May 17, 2020

@1ike @GollyJer I removed one hack and released 3.1.9. Can you both try it?

@1ike
Copy link

1ike commented May 17, 2020

@ai   with 3.1.9:

While trying to resolve module `nanoid/async` from file `D:\t\queue\Queue.js`, t
he package `D:\t\node_modules\nanoid\async\package.json` was successfully found.
 However, this package itself specifies a `main` module field that could not be
resolved (`D:\t\node_modules\nanoid\async\index.cjs`. Indeed, none of these file
s exist:

  * D:\t\node_modules\nanoid\async\index.cjs(.native|.android.expo.ts|.native.ex
po.ts|.expo.ts|.android.expo.tsx|.native.expo.tsx|.expo.tsx|.android.expo.js|.na
tive.expo.js|.expo.js|.android.expo.jsx|.native.expo.jsx|.expo.jsx|.android.ts|.
native.ts|.ts|.android.tsx|.native.tsx|.tsx|.android.js|.native.js|.js|.android.
jsx|.native.jsx|.jsx|.android.json|.native.json|.json|.android.wasm|.native.wasm
|.wasm|.android.svg|.native.svg|.svg)
 ......
Failed building JavaScript bundle.

@ai
Copy link
Owner

ai commented May 17, 2020

Do you use the latest Metro bundler.

This error reminds me old Metro problems with dual ESM/CJS packages.

@1ike
Copy link

1ike commented May 17, 2020

I updated Expo to 37, but nothing principally changed.

Unable to resolve "nanoid/non-secure" from "queue\Queue.js"
Failed building JavaScript bundle.
Unable to resolve "nanoid/non-secure" from "queue\Queue.js"

@ai
Copy link
Owner

ai commented May 17, 2020

Unable to resolve "nanoid/non-secure"

Did you have problem with resolving non-secure before? I thought that you have problems only with async.

@1ike
Copy link

1ike commented May 17, 2020

Sorry couple latest times I forgot switch to async. So now non-secure also is not working. With nanoid/async

Unable to resolve "nanoid/async" from "queue\Queue.js"
Failed building JavaScript bundle.

@ai
Copy link
Owner

ai commented May 17, 2020

So now non-secure also is not working

🙄 It is very strange. I didn’t change anything in the non-secure generator. Also, it is very strange that you two have different errors.

Are we sure, that builder and environment work correctly? Can I ask you to debug the system to find why non-secure stopped to work? (For instance, you can start from rebooting the OS).

@1ike
Copy link

1ike commented May 17, 2020

It is very strange.

It wasn't as strange as it was stupid - I forgot to install nanoid after removing. So non-secure still working. In contrast with nanoid/async which still have the same error.

@ai
Copy link
Owner

ai commented May 18, 2020

@1ike will import { nanoid } from "nanoid/async/index.native.js fix the problem?

@1ike
Copy link

1ike commented May 18, 2020

@ai Yeee, it fix all problems (this and this). Only a small trouble is that the linter criticizes such import.

@ai
Copy link
Owner

ai commented May 18, 2020

I mean that Metro continues to ignore package.json[react-native]. I created a few issues there, but the maintainer didn’t answer.

Can you try to add this lines to Metro config?

      resolver: {
        resolverMainFields: ['react-native', 'browser', 'main']
      }

and try normal import import { nanoid } from 'nanoid/async'?

@1ike
Copy link

1ike commented May 18, 2020

const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
	const {
		resolver: { sourceExts, assetExts }
	} = await getDefaultConfig();
	return {
		transformer: {
			babelTransformerPath: require.resolve("react-native-svg-transformer")
		},
		resolver: {
			assetExts: assetExts.filter(ext => ext !== "svg"),
			sourceExts: [...sourceExts, "svg"],
			resolverMainFields: ['react-native', 'browser', 'main']
		}
	};
})();

It did not help. Cause this error.

@ai
Copy link
Owner

ai commented May 18, 2020

@1ike does Expo change Metro config? Do it overrides resolverMainFields?

@GollyJer can resolverMainFields help you?

@1ike
Copy link

1ike commented May 18, 2020

does Expo change Metro config? Do it overrides resolverMainFields?

Sorry I don't know much about it (neither Expo or Metro).

@ai
Copy link
Owner

ai commented May 18, 2020

I added a full path notice to the docs b0fdb3e and migration guide.

Seems like we need to debug Metro builder and how Expo affects its config. I will need help from the Expo developer.

@1ike
Copy link

1ike commented May 19, 2020

BTW If import like 'nanoid/async/index.native' (w/o extension) then linter have no complaints. Only vscode still reminds about types: Could not find a declaration file for module 'nanoid/async/index.native'.

@ai
Copy link
Owner

ai commented May 27, 2020

@1ike thanks, I update code example https://github.com/ai/nanoid#react-native

@ai ai closed this as completed May 27, 2020
@TrySound
Copy link

TrySound commented Sep 9, 2020

@ai Looks like sync version support is added to expo
uuidjs/uuid#515

@ai ai reopened this Sep 9, 2020
@ai
Copy link
Owner

ai commented Sep 9, 2020

Can somebody send PR since I have no tools to test it?

@ctavan
Copy link
Contributor

ctavan commented Sep 10, 2020

We still have to wait for Expo SDK 39 to ultimately be released in order to test all of this on actual devices.

ctavan added a commit to ctavan/nanoid that referenced this issue Sep 10, 2020
ctavan added a commit to ctavan/nanoid that referenced this issue Sep 10, 2020
@diragb
Copy link

diragb commented Sep 16, 2020

BTW If import like 'nanoid/async/index.native' (w/o extension) then linter have no complaints. Only vscode still reminds about types: Could not find a declaration file for module 'nanoid/async/index.native'.

@ai facing this issue as well, it says that there's no ts support for index.native but i believe that nanoid/async/index.d.ts will suffice

ctavan added a commit to ctavan/nanoid that referenced this issue Dec 1, 2020
@ai ai closed this as completed in #231 Dec 1, 2020
ai pushed a commit that referenced this issue Dec 1, 2020
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.

9 participants