realm / realm-js

Realm is a mobile database: an alternative to SQLite & key-value stores
https://realm.io
Apache License 2.0
5.62k stars 558 forks source link

Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication) #4658

Closed 000xuandu closed 1 year ago

000xuandu commented 1 year ago

How frequently does the bug occur?

All the time

Description

@kneth

Hello guys!

As the title above, I'm facing the error after installing realm-js:
Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication)

This error was caused because has more than one react native version in my project. After check yarn.lock, I see that @realm/react@^0.3.1 has installed react-native@>=0.59 => This is causes error

Why @realm/react@^0.3.1 does install it?

And now, I can run my project until I remove the @realm/react package. (This means react-native@>=0.59 has been removed)

Pls, help me, How to resolve this case?

Stacktrace & log output

ERROR  TypeError: null is not an object (evaluating 'endpoint.startsWith')
 ERROR  Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect.
      This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
 LOG  redux-persist/stateReconciler: rehydrated keys 'app, user, _persist'
 ERROR  Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect.
      This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.

Can you reproduce the bug?

Yes, always

Reproduction Steps

No response

Version

"realm": "^10.19.1"
"@realm/react": "^0.3.1",

What SDK flavour are you using?

Local Database only

Are you using encryption?

No, not using encryption

Platform OS and version(s)

MacOS: 12.4 (21F79) 
iPhone OS: 15.4.1

Build environment

System:
    OS: macOS 12.4
    CPU: (8) x64 Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
    Memory: 273.85 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.14.1 - ~/.nvm/versions/node/v16.14.1/bin/node
    Yarn: 1.18.0 - /usr/local/bin/yarn
    npm: 8.5.0 - ~/.nvm/versions/node/v16.14.1/bin/npm
    Watchman: 2022.03.21.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.11.3 - /Users/mac/.rvm/gems/ruby-2.7.4/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 21.2, iOS 15.2, macOS 12.1, tvOS 15.2, watchOS 8.3
    Android SDK:
      API Levels: 23, 28, 29, 30, 31, 32
      Build Tools: 28.0.3, 29.0.2, 30.0.2, 30.0.3, 32.0.0
      System Images: android-27 | Google Play Intel x86 Atom, android-29 | Intel x86 Atom_64, android-30 | Google Play Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 2020.3 AI-203.7717.56.2031.7935034
    Xcode: 13.2.1/13C100 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.11 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2 
    react-native: 0.67.2 => 0.67.2 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Cocoapods version

CocoaPods: 1.11.3

tomduncalf commented 1 year ago

Hi @000xuandu, are you sure this is what is causing your error? That error can appear for a variety of reasons.

Installing Realm React should not install any version of react-native – it has a dev dependency of 0.65.1 but this will only be installed if you run npm install from the Realm React package root. It also has an optional dependency of React Native >0.59, but this is an open range allowing any version above 0.59, and should not override whatever you have specified in your project.

What do you see if you run npm list from your project root? I just created a test project with react-native@0.67.2 and the latest realm and realm-react, and see the expected result that there is only react-native@0.67.2 installed:

├── @babel/core@7.18.5
├── @babel/runtime@7.18.3
├── @react-native-community/eslint-config@2.0.0
├── @types/jest@26.0.24
├── @types/react-native@0.67.9
├── @types/react-test-renderer@17.0.2
├── @typescript-eslint/eslint-plugin@5.28.0
├── @typescript-eslint/parser@5.28.0
├── babel-jest@26.6.3
├── eslint@7.32.0
├── jest@26.6.3
├── metro-react-native-babel-preset@0.67.0
├── react-native@0.67.2
├── react-test-renderer@17.0.2
├── react@17.0.2
├── realm-react@0.1.0
├── realm@10.19.1
└── typescript@4.7.4
000xuandu commented 1 year ago

@tomduncalf Thanks!

Are you sure this is what is causing your error? That error can appear for a variety of reasons.

Yes, I'm leaning towards that reason. Because I just fixed this error (Invariant Violation...) with the same cause above (there is a more react-native version in yarn.lock file)

About your new project, why the latest version of realm-react is 0.1.0? Does it have much difference from 0.3.1?

IMPORTANCE: Since I installed realm, my project will work if I use commands such as: yarn ios, yarn android, but will appear as an error if I run the project by IDE such as Android Studio, or Xcode. Since then, the error appears even when I run using the command line.

To get the project working again with the command line, I had to remove node_modules, Pods, Podfile.lock, yarn install again, then I must restart my Macbook. After that, my project will work

Let me know your thoughts. If you need anything from me, don't hesitate!

tomduncalf commented 1 year ago

Sorry my mistake there, I installed realm-react (which is the old deprecated package name) rather than @realm/react!

I've created a new test project with the correct package and react-native@0.67.2 and it seems to work correctly. Here's my npm list result:

├── @babel/core@7.18.5
├── @babel/runtime@7.18.3
├── @react-native-community/eslint-config@2.0.0
├── @realm/react@0.3.1
├── babel-jest@26.6.3
├── eslint@7.14.0
├── jest@26.6.3
├── metro-react-native-babel-preset@0.66.2
├── react-native@0.67.2
├── react-test-renderer@17.0.2
├── react@17.0.2
└── realm@10.19.1

I've pushed the repo to https://github.com/tomduncalf/Issue4658AppRegistry if you'd like to try it out for yourself. If you're able to upload a repo reproducing the issue, that would be really helpful.

Thanks

000xuandu commented 1 year ago

@tomduncalf Thanks!

I'm having a problem with a company project, I'm thinking about publishing the project to GitHub or something like that. It would be an honor if you could join me to see the bug via Teamviewer. I can be online all the time!

tomduncalf commented 1 year ago

@000xuandu Could you please try to reproduce the problem in a new repository and share it if you are able to do so? That will be an easier first step than trying to look at your code over TeamViewer. Thanks

000xuandu commented 1 year ago

@tomduncalf OK! I will try it! I will let you know when I set up a new project!

000xuandu commented 1 year ago

@tomduncalf

Hi!

I just pushed code! (private Github) Link: https://github.com/000xuandu/rick-realm-4658

So, I send invite for you with email: tduncalf+github@gmail.com Pls, check it!

000xuandu commented 1 year ago

@tomduncalf

If has any problem with the invitation, pls let me know!

tomduncalf commented 1 year ago

Thanks @000xuandu, I got it and will take a look today!

tomduncalf commented 1 year ago

Hey @000xuandu, thanks for sharing your repro. I was able to start the application with no issues by following the instructions on the Github repo.

It might be worth clearing out all your node_modules etc., to check there's no conflict with some cached/old files there.

The following commands are our go-to "reset everything" for a React Native project, you may need to adapt them to your project:

rm -rf node_modules
npm cache clean -f
watchman watch-del-all
rm -rf $TMPDIR/metro*
rm -rf $TMPDIR/react-native*
npm install

rm -rf ios/Pods
rm ios/Podfile.lock
rm -rf ~/Library/Developer/Xcode/DerivedData
npx pod-install
000xuandu commented 1 year ago

@tomduncalf Thank you very much!

I was able to start the application with no issues by following the instructions on the Github repo.

Yes, right! But as I mentioned above, the error will appear when running the project by Xcode after running by instructions on the Github repo.

Can you try running my project by Xcode?

tomduncalf commented 1 year ago

Oh yeah that's strange, I was only able to start the app once and now I get the error. I will see if I can spot what is wrong here, unfortunately the RN error message is not very helpful!

000xuandu commented 1 year ago

@tomduncalf

Yes, that's right! It's hard to understand! In my mind, something seems to have been overwritten by Xcode!

tomduncalf commented 1 year ago

@000xuandu I've been trying to reproduce this on my end in a clean project and can't, I'm wondering if there's an issue in your application?

I do see the Invariant Violation error, however if I comment out line 59 of App.tsx (meteorCore.connect(Config.METEOR_CONNECT_URL)) then the error goes away. Are you able to try this out? Could it be that the error is coming from some unrelated part of the code?

000xuandu commented 1 year ago

@tomduncalf Oh, Exactly! Now, I can run my project! Thank you!

Can you share with me how you find this issue?

tomduncalf commented 1 year ago

My usual approach with "weird" React Native issues is to strip the app down to the absolute basics, to check that it works in that case – so I replaced the contents of App.tsx with just something like:

import React from 'react';
import { Text } from 'react-native';

export default () => {
  console.log('hello');

  return <Text>hello</Text>;
};

This way, none of your application code or dependencies are being imported. Then I restart the app and check that I see "hello" on the screen and/or in the logs.

Assuming that the "hello" example works, I then take a kind of "binary search" approach to finding out what is causing the app to break, by restoring the original App.tsx and commenting out nearly everything so that it just renders something simple, and then gradually uncommenting sections until I hit the error. You could also paste chunks back in to the stripped out file, but I find uncommenting to be a bit easier.

For example in your case, I first uncommented the imports, and saw that the app still loaded OK, then I uncommented the code in the component body, and saw that the app still loaded OK, then finally I uncommented the code above the component and saw this caused it to fail. I then tried commenting out different chunks of that bit of code, until I found the offending line.

I find this approach can be really useful when you're debugging something really weird with no useful stack trace (which happens quite a lot in React Native 🤣), and can scale to finding which part of a file somewhere deep down the component hierarchy is causing issues.

Hope that helps! Are you happy for me to close your issue?

000xuandu commented 1 year ago

@tomduncalf WOW! Thank you very much! Very helpful!

But I still have a bug EXC_BAD_ACCESS, which makes my app crash! I think the EXC_BAD_ACCESS bug was caused by Realm! I couldn't find this error earlier because the Invariant Violation, and EXC_BAD_ACCESS error didn't appear in Javascript

To reproduce, in my project, please pull the latest commit and follow me in the video, the app will crash and we see the error in Xcode.

My app crashed on iOS and Android!

https://user-images.githubusercontent.com/33916400/174835706-b3bc4746-3b59-4e0f-bde5-20690ba8620e.mov

tomduncalf commented 1 year ago

Hey @000xuandu, what makes you think this error is related to Realm? Is the app doing something with Realm at the point where it crashes? If so, what is it doing?

000xuandu commented 1 year ago

@tomduncalf Yes, I use Realm to create/update some data!

Please pull the latest commit!

At line 331 on the useAuthAPI file, I begin using Realm. Also, I don't use Realm anywhere anymore!

Here, I divided it into 2 cases, CASE1: DON'T CRASH, and CASE2: WILL CRASH, default is CASE1: DON'T CRASH To switch those cases, just comment out/uncomment!

what makes you think this error is related to Realm?

When I use CASE1 it means don't use realm => don't crash! When I use CASE2 it means use realm => crash!

Please check it, thanks!

https://user-images.githubusercontent.com/33916400/175014327-2eedd053-7d48-4850-86bd-f297cbdab50c.mov

https://user-images.githubusercontent.com/33916400/175014417-293c0b73-e06f-4060-9c5a-c45d03fbb1b7.mov

tomduncalf commented 1 year ago

Can you point me to where the write to Realm happens once you have updated your profile picture? I see it calling updateUserInfo in userSlice but I'm not clear how this ends up writing to Realm. It seems that the loginWithoutAccount function is called without any errors earlier in the flow

000xuandu commented 1 year ago

@tomduncalf

Yes, I don’t update profile picture into Realm, just update into redux! I only use Realm to create user at useAuthAPI file! That’s difficult to debug!

tomduncalf commented 1 year ago

Hey @000xuandu, what could maybe be happening here is that when you are putting the user and account profile objects in your Redux store, they are actually still somehow "live" Realm objects in some way... So when you then modify the profile_pic property of the user, the app crashes – maybe because you're inadvertently modifying a Realm object without being in a write transaction, or maybe something else is going on.

I'm not really sure why this would be happening, as I'd expect the call to toJSON() to make the object into a plain JS object.

I'll look into this in more detail to see if it is a bug on our end, but for now it seems you can work around this by using the "stringify then parse" trick to convert the objects into plain JS objects before storing them:

      dispatch(updateUserInfo(JSON.parse(JSON.stringify(userRealm.toJSON()))))
      dispatch(
        setAccountProfiles(
          JSON.parse(JSON.stringify([accountProfileRealm.toJSON()])),
        ),
      )

I'll follow up once I find out more about why toJSON does not seem to be working here!

000xuandu commented 1 year ago

@tomduncalf

Probably so! Thank you so much! The "stringify then parse" trick looks nasty, but that's okay, I hope it works! I hope toJSON() will work as its name!

When you have something new, let me know! And now this issue you think should close it?

tomduncalf commented 1 year ago

Yeah, it is nasty 🤣 I think you only need to do it for userRealm actually. Once I understand more about this I might create a new issue with better details about the toJSON issue, but we can leave this one open for now.

000xuandu commented 1 year ago

OK! 😆 Let me know when has something new! And I hope that I will receive new info from you soon! 👍

tomduncalf commented 1 year ago

@000xuandu I'm struggling to create a reproduction of your issue outside of the context of your app, or even inside your app – I tried making a function which calls:

continueWithoutAccount()
onSetImageUri('whatever')

when pressing a Button, which I'd expect to cause the same issue, but it does not.

As I'm unfamiliar with your application architecture there's a limit to what I can do without a simpler reproduction case – would you be able to try to create a reproduction in a standalone project, or with as minimal an amount of code as possible? Right now there's a lot going on so it's hard for me to pin down exactly where the issue is, or how it relates to Realm. Thanks!

000xuandu commented 1 year ago

@tomduncalf

Oh, I got it!

My logic is as simple as this:

  1. Create a user realm object (has profile_pic or something like that) and save it to redux (userInfo)
  2. At somewhere, get the userInfo object from redux and update profile_pic

That's all

tomduncalf commented 1 year ago

@000xuandu OK good news, I've been able to create a test project which reproduces your issue. What seems to be happening is that, as suspected, toJSON is not fully converting the Realm object to a plain JS object – the profile property remains a JS Proxy, which is then somehow causing this error.

Now I've got a simple reproduction, hopefully I can find a solution for this! I'll keep you updated, thanks for your patience.

000xuandu commented 1 year ago

@tomduncalf OK! I am always here! Haha

tomduncalf commented 1 year ago

Hey @000xuandu, I tracked down the root cause of the bug (JavaScriptCore, used by React Native on iOS, has a buggy Proxy implementation – in this case we were calling x instanceOf Dictionary, which should return true for a proxied Dictionary as the Proxy should be totally transparent, but on JSC it was returning false) and implemented a workaround in https://github.com/realm/realm-js/pull/4674. Once reviewed and merged, we'll create a new release of Realm JS – I'll let you know when this is out for you to test it.

Thanks for reporting this, it's a pretty subtle bug!

tomduncalf commented 1 year ago

@000xuandu We have just released Realm JS 10.19.3 which should fix this issue, please let us know if you are still having problems.

000xuandu commented 1 year ago

@tomduncalf Oh oh, sorry for the late reply! I will check it right now.

000xuandu commented 1 year ago

@tomduncalf

It's worked for me. Thanks!

"@realm/react": "^0.3.2",
"realm": "^10.19.5",