Invariant Violation: AsyncStorage has been removed from react-native core. It can now be installed and imported from '@react-native-async-storage/async-storage' instead of 'react-native'.

SDK Version: “expo”: “^48.0.0”

I recently upgraded my expo project from 42 to 48. I keep getting 2 errors which i dont understand. The project is really urgent.;

“Invariant Violation: AsyncStorage has been removed from react-native core. It can now be installed and imported from ‘@react-native-async-storage/async-storage’ instead of ‘react-native’. See GitHub - react-native-async-storage/async-storage: An asynchronous, persistent, key-value storage system for React Native., js engine: hermes”

"Invariant Violation: “main” has not been registered. This can happen if:

  • Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project."

Hi @wokeupsober

Did you upgrade straight from Expo SDK 42 to 48? I normally find it better to do one version at a time. Also, did you read all of the release notes and deal with any breaking changes for the versions between SDK 42 and 48?

You’ll need to install @react-native-async-storage/async-storage and then change the imports from:

import { AsyncStorage } from 'react-native';

to:

import AsyncStorage from '@react-native-async-storage/async-storage';

This can be caused by various things. First fix the AsyncStorage issue and see if this is still a problem.

If it is, try running npx expo-doctor and see if that warns about anything.

Hey, i upgraded expo step by step from 42 to 48. i already installed @react-native-async-storage/async-storage. But there is no use of that format of Async in the project. Then i ran npx expo-doctor and it gave the following,

C:\Users\hp\Garden App updated\garden-app> npx expo-doctor WARNING: We recommend using PowerShell or Bash via WSL 2 for development with Expo CLI on Windows. You may encounter issues using cmd.exe.

√ Validating global prerequisites versions passed √ Checking for incompatible packages passed √ Checking for conflicting global packages in project passed √ Verifying prebuild support package versions are compatible passed × Checking dependency versions for compatibility with the installed Expo SDK failed Issues:
'sh' is not recognized as an internal or external command, operable program or batch file. Advice:
• Use npx expo install --check to review and upgrade your dependencies. √ Validating Expo Config passed √ Checking package.json for common issues passed

✖ Found one or more possible issues with the project. See above logs for issues and advice to resolve.

C:\Users\hp\Garden App updated\garden-app>npx expo install --check Dependencies are up to date

Hi- apologies for the issue there. It looks like there’s a problem running part of Doctor on Windows. We’ll work on fixing this. In the meantime, you can run npx expo install --check to perform basically the same step that’s failing. The only difference is that it will prompt you to update the dependencies, as well.

It says
Dependencies are up to date

But throws up the same above errors

I tried but it still doesnt work

Could you post your dependencies and devDependencies from package.json.

And your plugins section from app.json (if you are using any config plugins).

Also, do you have an android or ios directory in the app?

When do you get these errors, exactly?

package.json

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  "dependencies": {
    "@material-ui/core": "^4.12.3",
    "@react-native-async-storage/async-storage": "1.17.11",
    "@react-native-community/datetimepicker": "6.7.3",
    "@react-native-community/masked-view": "0.1.10",
    "@react-native-community/picker": "1.6.6",
    "@react-native-picker/picker": "2.4.8",
    "@react-navigation/bottom-tabs": "^5.8.0",
    "@react-navigation/drawer": "^5.12.9",
    "@react-navigation/material-bottom-tabs": "^5.3.19",
    "@react-navigation/native": "^5.9.8",
    "@react-navigation/stack": "^5.14.9",
    "expo": "^48.0.0",
    "expo-constants": "~14.2.1",
    "expo-font": "~11.1.1",
    "expo-notifications": "~0.18.1",
    "expo-permissions": "~14.1.1",
    "expo-status-bar": "~1.4.2",
    "expo-updates": "~0.16.4",
    "firebase": "8.2.3",
    "flutterwave-react-native": "^1.0.2",
    "immutable": "^4.0.0",
    "moment": "^2.29.1",
    "native-base": "^2.15.2",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-native": "0.71.7",
    "react-native-auth0": "^2.6.0",
    "react-native-carousel-cards": "^1.2.1",
    "react-native-datepicker": "^1.7.2",
    "react-native-dropdownmenus": "^1.0.6",
    "react-native-elements": "^2.3.1",
    "react-native-gesture-handler": "~2.9.0",
    "react-native-interactable-reanimted": "0.0.4",
    "react-native-modal": "^13.0.0",
    "react-native-numeric-input": "^1.8.3",
    "react-native-paper": "^4.9.2",
    "react-native-picker-select": "^8.0.4",
    "react-native-popup-menu": "^0.15.9",
    "react-native-reanimated": "~2.14.4",
    "react-native-safe-area-context": "4.5.0",
    "react-native-screens": "~3.20.0",
    "react-native-shapes": "^0.1.0",
    "react-native-simple-toast": "^1.1.3",
    "react-native-svg": "13.4.0",
    "react-native-svg-transformer": "^0.14.3",
    "react-native-swiper-flatlist": "^3.0.15",
    "react-native-vector-icons": "^7.1.0",
    "react-native-web": "~0.18.7",
    "react-native-webview": "11.26.0",
    "react-navigation-drawer": "^2.7.1",
    "react-redux": "^7.2.1",
    "reanimated-bottom-sheet": "^1.0.0-alpha.22",
    "redux": "^4.0.5",
    "rn-sliding-up-panel": "^2.4.4",
    "styled-components": "^5.3.1",
    "styled-system": "^5.1.5"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "babel-preset-expo": "^9.3.0"
  },
  "private": true
}

app.json

{
  "expo": {
    "name": "groce-app",
    "slug": "groce-app",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#21b464"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true
    },
    "android": {
      "package": "com.groce_app.wgt",
      "versionCode": 1,
      "softwareKeyboardLayoutMode": "pan",
      "googleServicesFile": "./google-services.json"
    },
    "web": {
      "favicon": "./assets/favicon.png"
    },
    "plugins": [
      [
        "expo-notifications",
        {
          "icon": "./local/path/to/myNotificationIcon.png",
          "color": "#ffffff",
          "sounds": ["./local/path/to/mySound.wav", "./local/path/to/myOtherSound.wav"],
          "mode": "test"
        }
      ]
    ]
  }
}

Would you mind answering the following?

No i do not have, i get the errors on the Expo app on my phone

Can i send the Repo?

Sure. Maybe I can look at it on the weekend

Thank you. Here is the repo link

I’ve had a look and this is what I’ve found:

  1. You have both yarn.lock and package-json.lock. You should only have one of these. You should decide whether to use yarn or npm for managing your dependencies. Don’t use both. e.g. if you decide to use yarn you should remove package-lock.json. If you decide to use npm you should remove yarn.lock.
  2. You have a lot of dependencies that you aren’t using. You should get rid of them.
  3. You’re not directly using AsyncStorage, so you should not have it listed as a dependency.
  4. The error about AsyncStorage is actually coming from Firebase. I see you have the firebase package installed, but it seems that these days you should use the following instead:
@react-native-firebase/app
@react-native-firebase/auth
@react-native-firebase/firestore

I don’t use Firebase myself, so I’m not sure exactly what you need to do to migrate to these. Check the https://rnfirebase.io/ documentation.

I think you’ll also need to create a development build to use instead of the Expo Go app.

So, something like this:

diff --git package.json package.json
index 453c08c..c91a2d8 100644
--- package.json
+++ package.json
@@ -4,17 +4,12 @@
     "start": "expo start",
     "android": "expo start --android",
     "ios": "expo start --ios",
-    "web": "expo start --web",
-    "eject": "expo eject"
+    "web": "expo start --web"
   },
   "dependencies": {
-    "@material-ui/core": "^4.12.3",
-    "@react-native-async-storage/async-storage": "1.17.11",
-    "@react-native-community/datetimepicker": "6.7.3",
-    "@react-native-community/masked-view": "0.1.10",
-    "@react-native-community/picker": "1.6.6",
+    "@react-native-firebase/app": "^17.5.0",
+    "@react-native-firebase/auth": "^17.5.0",
     "@react-native-picker/picker": "2.4.8",
-    "@react-navigation/bottom-tabs": "^5.8.0",
     "@react-navigation/drawer": "^5.12.9",
     "@react-navigation/material-bottom-tabs": "^5.3.19",
     "@react-navigation/native": "^5.9.8",
@@ -23,26 +18,21 @@
     "expo-constants": "~14.2.1",
     "expo-font": "~11.1.1",
     "expo-notifications": "~0.18.1",
-    "expo-permissions": "~14.1.1",
     "expo-status-bar": "~1.4.2",
     "expo-updates": "~0.16.4",
-    "firebase": "8.2.3",
     "flutterwave-react-native": "^1.0.2",
     "immutable": "^4.0.0",
     "moment": "^2.29.1",
     "native-base": "^2.15.2",
     "react": "18.2.0",
     "react-dom": "18.2.0",
-    "react-native": "0.71.7",
-    "react-native-auth0": "^2.6.0",
+    "react-native": "0.71.8",
     "react-native-carousel-cards": "^1.2.1",
     "react-native-datepicker": "^1.7.2",
     "react-native-dropdownmenus": "^1.0.6",
     "react-native-elements": "^2.3.1",
     "react-native-gesture-handler": "~2.9.0",
-    "react-native-interactable-reanimted": "0.0.4",
     "react-native-modal": "^13.0.0",
-    "react-native-numeric-input": "^1.8.3",
     "react-native-paper": "^4.9.2",
     "react-native-picker-select": "^8.0.4",
     "react-native-popup-menu": "^0.15.9",
@@ -52,22 +42,15 @@
     "react-native-shapes": "^0.1.0",
     "react-native-simple-toast": "^1.1.3",
     "react-native-svg": "13.4.0",
-    "react-native-svg-transformer": "^0.14.3",
     "react-native-swiper-flatlist": "^3.0.15",
     "react-native-vector-icons": "^7.1.0",
     "react-native-web": "~0.18.7",
-    "react-native-webview": "11.26.0",
-    "react-navigation-drawer": "^2.7.1",
-    "react-redux": "^7.2.1",
     "reanimated-bottom-sheet": "^1.0.0-alpha.22",
-    "redux": "^4.0.5",
-    "rn-sliding-up-panel": "^2.4.4",
-    "styled-components": "^5.3.1",
     "styled-system": "^5.1.5"
   },
   "devDependencies": {
     "@babel/core": "^7.20.0",
-    "babel-preset-expo": "^9.3.0"
+    "react-native-svg-transformer": "^1.0.0"
   },
   "private": true
 }

Thanks for the help. Is there a way to know which dependencies that arent working/in use. The Package.json is how mine should look right? can i just copy it into mine and run npm install

There might be a better way of doing it (e.g. maybe there is a VS Code plugin or something that can do it), but basically I made a list of all of the import statements like this. I did this on macOS. The git grep commands should work on Windows too, I think:

First the ones where you used single quotes:

git grep "from '" -- "**/*.js" > imports.txt

Then I appended the ones with double quotes to the file:

git grep 'from "' -- "**/*.js" >> imports.txt

Then I opened the file in my text editor (Vim) and did some search and replace and ran it through “sort -u” to get the unique ones like this:

@expo/vector-icons
@react-native-picker/picker
@react-navigation/drawer
@react-navigation/material-bottom-tabs
@react-navigation/native
@react-navigation/stack
expo-constants
expo-font
expo-notifications
expo-status-bar
expo-updates
firebase
flutterwave-react-native
immutable
moment
native-base
react
react-native
react-native-carousel-cards
react-native-datepicker
react-native-dropdownmenus
react-native-elements
react-native-gesture-handler
react-native-modal
react-native-paper
react-native-picker-select
react-native-popup-menu
react-native-reanimated
react-native-shapes
react-native-simple-toast
react-native-swiper-flatlist
react-native-vector-icons/FontAwesome5
reanimated-bottom-sheet
styled-system

I then compared that with your dependencies in package.json.

These ones aren’t in your list of imports. (If you do plan to use masked-view in future you should switch to @react-native-masked-view/masked-view because the community version is deprecated.)

This is like MaskedView. The community version is deprecated and it seems you switched to the correct one, but left the community version in your dependencies.

This is no longer part of the Expo SDK and should be removed. You’re not using it anymore anyway.

These are also not in your import statements. Also, react-navigation-drawer is old and was replaced by @react-navigation/drawer.

These two I left in, because although you don’t use them directly, they’re needed by React Navigation

I haven’t used Styled Components before. I found styled-system in your imports, but not styled-components. Just based on the names and similar version numbers I thought these two dependencies might be related. Since styled-components doesn’t appear in your imports I removed it from the dependencies. But it could be that it’s needed by styled-system, similar to react-native-safe-area-context and react-native-screens for React Navigation. If you get errors you might need to add this one back again.

These two are not in your imports, and I initially removed them, but when I tried running npx expo start it complained about react-native-svg-transformer being missing. That’s referenced in your metro.config.js. So I added it back. There was then an error about react-native-svg. I added that back too. When I added react-native-svg-transformer back again I added it as a dev dependency, since it’s only needed during development/building the app and not while the app is actually running.

I also got a warning about the react-native version which I fixed by running npx expo install --check and letting it update the version.

I know from past experience that this is no longer needed. I think functionality was incorporated into @babel/core, so I removed it. Although @babel/core is not in your imports it is needed.

These days there’s no such thing as expo eject, so I removed this.

After making the changes to package.json, I ran yarn to apply the changes to node_modules and yarn.lock. (If you decide to use npm then get rid of yarn.lock. I removed package-lock.json)

At this point the app still ran in Expo Go, but I was getting the same errors as you were. So, since you are not using AsyncStorage yourself it must be one of the dependencies. I did a recursive search through node_modules. This grep command won’t work for you on Windows, but would work e.g. in WSL (Windows Subsystem for Linux). There is probably a Windows tool that can do something like this too:

% grep -rl "AsyncStorage" node_modules
node_modules/@types/react-native/index.d.ts
node_modules/expo-file-system/build/FileSystem.js
node_modules/expo-file-system/build/FileSystem.js.map
node_modules/expo-file-system/build/FileSystem.d.ts
node_modules/expo-file-system/src/FileSystem.ts
node_modules/react-native/CHANGELOG.md
node_modules/react-native/index.js
node_modules/firebase/firebase.js.map
node_modules/firebase/firebase-auth.js
node_modules/firebase/firebase.js
node_modules/firebase/firebase-auth.js.map
node_modules/@expo/cli/README.md
node_modules/metro-react-native-babel-preset/src/configs/lazy-imports.js

All of that is related to React Native, Metro and Babel or Expo, except for the firebase ones. So firebase must be the culprit.

Although I haven’t used Firebase before I know there used to be some expo-firebase-* packages that were removed in Expo SDK 48 (or maybe 47?). I’m not sure about firebase. As far as I know people use the @firebase/* ones now.

What I posted in my last message was a “diff” (technically a “unified diff”). I generated it by running git show -- package.json after committing the changes. I could also have got the same thing by running git diff after making the changes, but before committing them.

Basically what it means is that I removed all of the lines starting with a “-” and added all of the lines starting with a “+” (but the “+” is just to show the new lines. You should not have them in the actual file.)

The lines like this just mean this section corresponds with lines 4 to 17 in the old version (-) and lines 4 to 12 in the new version (+) of the file. These lines should also not be included in the actual file.

Editing the file manually could introduce errors, so you might want to run a bunch of npm uninstall xxx commands instead to remove all of the ones you don’t need. When installing dependencies it’s usually best to use npx expo install xxx which calls either yarn add xxx or npm install xxx for you. In the case of Expo packages and a few others, it will make sure that a compatible version of the package is installed. For things that it does not know about it will just install the latest version.

I hope that clarifies everything :slight_smile:

Hey there, thanks for the help.I’m really still new to this but let me break it down from own understanding

Step 1: run git grep "from '" -- "**/*.js" > imports.txt to see list of dependencies with single quotes.

step 2: run git grep 'from "' -- "**/*.js" >> imports.txt to see list of dependencies with double quotes.

step 3: Then run npm uninstall for the following irrelevant dependencies.

"@material-ui/core": "^4.12.3",
"@react-native-async-storage/async-storage": "1.17.11",
"@react-native-community/datetimepicker": "6.7.3",
"@react-native-community/masked-view": "0.1.10",
"@react-native-community/picker": "1.6.6",
"@react-native-picker/picker": "2.4.8",
"expo-permissions": "~14.1.1",
"react-native-auth0": "^2.6.0",
"react-native-interactable-reanimted": "0.0.4",
"react-native-numeric-input"
"react-native-webview"
react-navigation-drawer {upgrade this version to @react-navigation/drawer}
react-redux
redux
rn-sliding-up-panel “babel-preset-expo”: “^9.3.0”`

step 4: Leave the following because they are important.

 ` "react-native-safe-area-context": "4.5.0",`
`"react-native-screens": "~3.20.0",`

"styled-components": "^5.3.1",
"styled-system": "^5.1.5"

"react-native-svg": "13.4.0",
"react-native-svg-transformer": "^0.14.3",

Question: What is the difference between Dev Dependencies and regular dependencies and how to install differently.

Step 5: update react native version with npx expo install --

Question: How do i remove "eject": "expo eject"

Step 6: Always remember to install dependencies with npx expo install xxx

Step 7: The issue comes from firebase so i need to remove Async completely and read the React Native Firebase docs and not regular Firebase

These will search your Git repository for lines containing either:

from '

or

from "

The first one creates a file called imports.txt and the second one appends to the same file. You can open it in a text editor, but as-is it’s a bit messy. I tidied it up before using it.

According to your imports you’re not currently using this, so just uninstall it. Don’t install @react-navigation/drawer.

yes

I am not 100% sure, but I think you can get rid of styled-components too. But styled-system is being imported, so keep that.

Yes.

devDependencies are things that are not used by the app while it’s running on a user’s device. They are normally things that are used during development or when building the code into an app.

You install them with something like:

npm install --save-dev the-dev-dependency

or

yarn add -D the-dev-dependency

Yes, npx expo install --fix will do it.

You can just edit the file. But be careful not to leave a trailing comma on the previous line if it’s the last line in the scripts section, because that’s a syntax error in JSON.

e.g.:

"scripts": {
  "key1": "value1",    <- this comma is required
  "key2": "value2",    <- trailing comma is a syntax error because it's the last thing before the "}"
}

Generally best, yes.

Yes, uninstall the firebase dependency and then follow the RN Firebase docs for how to install and use @react-native-firebase/app and @react-native-firebase/auth.

I think there’s also a plain JavaScript version of Firebase, but it’s more limited and I’m not sure what exactly you can/can’t do with it.

Hey i followed the steps and removed the unnecessary dependencies and upgraded the necessary ones. With your help i reached the Firebase aspect and changed
from import * as firebase from "firebase"; to import firebase from "firebase/compat/app"

Then the terminal brought

The issue now is that it throws up the following errors;

  1. `Invariant Violation: “main” has not been registered. This can happen if:
  • Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
  • A module failed to load due to an error and AppRegistry.registerComponent wasn’t called., js engine: hermes
  1. TypeError: undefined is not a function, js engine: hermes

Should i commit the new changes on my end so you could have an ideaof what i’m talking about?

OK. I’ll have a look