AsyncStorage from @RNC?

The Expo docs for AsyncStorage (https://docs.expo.io/versions/latest/sdk/async-storage/) instruct to use expo install @react-native-community/async-storage, but I’m getting an error when building my app:

Error: [@RNC/AsyncStorage]: NativeModule: AsyncStorage is null

AsyncStorage works as intended when using expo start, but not after building.

Looking at previous posts this seems to be a problem with Expo not supporting @react-native-community/async-storage, and that I should import AsyncStorage from react-native.

Is this an error with the Expo docs, or is this caused by something else? I am using SDK 39.

I’ve just written a simple app that fetches from/writes to AsyncStorage. It works in development and it also works after building a standalone APK. This is of course also SDK 39.

Just to make sure, are you importing AsyncStorage from @react-native-community/async-storage or react-native (deprecated)?

Importing from react-native works without errors for me, but importing from @react-native-community/async-storage causes the error after installing the built .apk.

I imported from @react-native-async-storage/async-storage. I had no problem installing/running the built APK on my phone.

This was the test app:

import { StatusBar } from "expo-status-bar";
import React, { useEffect, useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

function storeData(value) {
  AsyncStorage.setItem("@storage_Key", value)
    .then(() => {
      console.log("Stored value", value);
    })
    .catch((e) => {
      alert("Error saving to AsyncStorage:" + JSON.stringify(e));
    });
}

function getData(setData) {
  AsyncStorage.getItem("@storage_Key")
    .then((value) => {
      console.log("Got value", value);
      setData(value);
    })
    .catch((e) => {
      console.log("Error reading from AsyncStorage: " + JSON.stringify(e));
    });
}

export default function App() {
  const [data, setData] = useState("initial");
  const [stored, setStored] = useState("");

  useEffect(() => {
    getData(setData);
  }, []);

  useEffect(() => {
    const timer = setTimeout(() => {
      const value = JSON.stringify(new Date());
      storeData(value);
      setStored(value);
    }, 3000);
    return () => clearTimeout(timer);
  }, []);

  return (
    <View style={styles.container}>
      <Text>Stored: {stored}</Text>
      <Text>Fetched: {data}</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

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": {
    "@react-native-async-storage/async-storage": "^1.13.2",
    "expo": "~39.0.2",
    "expo-status-bar": "~1.0.2",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-39.0.4.tar.gz",
    "react-native-web": "~0.13.12"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0"
  },
  "private": true
}