react-native: AsyncStorage.getItem() doesn't seem to work

When I try to set a value via AsyncStorage.getItem(), I cannot request it back.

Environment

Environment: OS: macOS High Sierra 10.13.3 Node: 9.8.0 Yarn: 1.5.1 npm: 5.6.0 Watchman: 4.9.0 Xcode: Xcode 9.2 Build version 9C40b Android Studio: Not Found

Packages: (wanted => installed) react: ^16.3.0-alpha.1 => 16.3.0-alpha.1 react-native: 0.54.0 => 0.54.0

Expected Behavior

await AsyncStorage.setItem('foo', 'bar');
await AsyncStorage.getItem('foo').then(console.log); // 'bar'
await AsyncStorage.getAllKeys().then(console.log); // ['foo']

Actual Behavior

await AsyncStorage.setItem('foo', 'bar');
await AsyncStorage.getItem('foo').then(console.log); // null
await AsyncStorage.getAllKeys().then(console.log); // []

Steps to Reproduce

import { AsyncStorage } from 'react-native';

it('should be able to request a value after it was set', async () => {
  await AsyncStorage.setItem('foo', 'bar');
  const output = await AsyncStorage.getItem('foo');

  expect(output).toBe('bar');
});

it('should be able to see a new key after a value was set', async () => {
  await AsyncStorage.setItem('foo', 'bar');
  const output = await AsyncStorage.getAllKeys();

  expect(output).toContain('foo');
});

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 54
  • Comments: 108 (1 by maintainers)

Commits related to this issue

Most upvoted comments

It’s 2 years bug, same with hot reload bug. These bugs are so old that they are mascots for the RN. Now I understand why Airbnb is dropping RN.

Just to add to this, I’ve noticed that if I am using AsyncStorage.getItem() and I make a change in a file, to trigger a live reload of the application in the emulator, but then at the same time its recompiling the JS, I then save once again, to interupt and trigger a new compilation, then it stops working and requires me to restart the application (react-native run-android again)

I have tested this problem thoroughly as I originally thought it was the elusive JS bug where not logging something would cause it to disappear, and I have found that the behaviour of AsyncStorage is random at best.

We have tested on 10 Android devices with different makes and models, all with decent amounts of RAM and free storage space. We also tested with the last 4 iPhones released. Tested with Expo as well as the last 3 versions of React Native.

  • setItem seems to work as far as setting the item around 80% of the time, but blocks the main thread as it executes an astonishing ~90% of the time
  • getItem works around 25% of the time, and if it fails then it blocks the entire thread, does NOT form an error, and can only be resolved by force closing the app, waiting 10 seconds, and then opening it again
  • getItem is totally unpredictable and can return older values even though there is no “race” present
  • the callback for getItem/setItem is rarely if ever called, even upon successful execution
  • if the callback is called, it rarely if ever is able to set the state of the application. the only way around this is a series of ugly binds and making the function it runs a method of the component
  • in expo, asyncstorage almost never works, and when it does, it blocks the thread about a minute after its execution (as in, it will return the right value, code will execute, and about a minute in everything will freeze on the thread it was on), and the only solution to this is to put it in a separate async function and not bind it at all to the component
  • getAllKeys works in less than 2% of our total runs
  • turning on debug in chrome remotely drops all success rates to 0, which means debugging asyncstorage is close to impossible
  • building the APK does NOT fix anything
  • the issue persists at about the same rate in every version of react native
  • the magic number: if you get asyncstorage to work in a full cycle (getItem, setItem) once, then that specific installation of the app will be able to use asyncstorage with a 100% success rate for all operations
  • sometimes it only blocks console.log and nothing else
  • Expo SecureStorage does not face these issues but they use Keychains as their backend

👻 SPOOKY bugs just in time for Halloween!

Experiencing the same issue, AsyncStorage is just unusable.

Having the same issue with 0.52.0. Really frustrating.

If you call setItem and then immediately call getItem or getAllKeys to reveal all in the store it works as normal and the value will be present. Reload of the app and back to square one, getItem returns null.

by converting data to stringify and then setItem … and after getting it converting it back work for me … setting data: AsyncStorage.setItem(‘saveData’, JSON.stringify(value)); getting data: AsyncStorage.getItem(‘saveData’).then((value) => {

    data=JSON.parse(value);

}).done();

worked for me…

So the solution here is to

localdatabase.js
import { AsyncStorage } from 'react-native';
import _ from 'lodash';
export  const setItem= async(key, value) =>{
    try {
        return await AsyncStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
        // console.error('AsyncStorage#setItem error: ' + error.message);
    }
}
export const getItem = async(key)=> {
    return await AsyncStorage.getItem(key)
        .then((result) => {
            if (result) {
                try {
                    result = JSON.parse(result);
                } catch (e) {
                    // console.error('AsyncStorage#getItem error deserializing JSON for key: ' + key, e.message);
                }
            }
            return result;
        });
}
export const  removeItem = async(key)=> {
    return await AsyncStorage.removeItem(key);
}

Use that file as :

import {setItem,getItem} from './localdatabase';
getValuesFromDb= async()=>{
    const key1 = await getItem('1').then((result) => this.setState({ index1: result }));
    const key2 = await getItem('2').then((result) => this.setState({ index2: result }));
    }
  }

Make sure to run

yarn run android or ios everytime you make a change; This makes it easy to write the code and the async storage works without any issues. Also when building for production it works like charm the issue is when you connect the debugger or enable hot loading it fucks up.

Sounds like no one from maintainers is interested in this issue.

Any update on this?

Same issue for me. It is such a shame that a such critical and old issue is not being solved.

To all of those still experiencing the issue, the SecureStore from Expo is a viable alternative, which has APIs signatures very similar to AsyncStorage and already comes bundled with Expo. That solved the issue for me.

let value = await AsyncStorage.getItem(“user”);
this line blocks the execution … the next line is not working …
i am using … “react-native”: “0.55.3” and android one device… its frustating…

Experiencing this issue in production with a single AsyncStorage.getItem. Sometimes it works, sometimes it just returns null.

Will this ever be fixed ?

try {
     console.log('start')
     await AsyncStorage.getItem('token');
     alert('end') // << This never executes!
}catch(err){
     console.log(err);
 }

Same problem. The AsyncStorage.getItem() and the code followed never execute. No error at all. I’m using react-native-navigation v2 and react native 0.56.

Have you remembered to put the item in asyncstorage as string (JSON.stringify) and when reading the parse item (JSON.parse) ?? this may be the mistake of many.

Problem is not getItem, the problem is setItem or that I think. The difference between getItem and setItem is that set not return something (except a null). So, the await of setItem never pass to the next set. Actually, even never set the data.

So, the solution (at least for me) is: not to use await in setItem.

do i have another way to replace asyncStorage for this issue?

You can write a batch file to do the following

adb shell am force-stop com.YOUR-PACKAGE-NAME adb shell am start com.YOUR-PACKAGE-NAME/com.YOUR-PACKAGE-NAME.MainActivity

Run this batch file instead of pressing RR on the emulator

same here … let result = await AsyncStorage.getItem(key) android just stuck there , try catch not work, only restart the app again or setting a timeout, but it is not a solution. It still cannot load the data saved.

I am thinking to use this as alternative : https://github.com/oblador/react-native-keychain Edit: I was already using react-native-fs for my project. so, I used it to store a file containing JSON data, and fetched back on program starts. I know its not the right way. but its working perfectly, and I am really scared of using AsyncStorage now.

Try to run the install command again, it may to work.

Same problem here lol

Hey Guys , I think I found the problem for myself ,it may seems stupid for you but what I did to work is just disable debug JS remotely and without logging my data inside AsyncStorage ,seems it’s working every time that I need the data , so the solution for me was to disable Debug JS Remotely on Chrome , then it works perfectly , hopefully it solves other problem .

I had the same problem and I found the reason was I was just going to fast for what the bundler could handle. I was often saving several changes in several files in close succession and what @AleskiWeb described was happening. I had to slow down and wait for the bundler to finish rebundling each time I save a file before I could save another. If you do it by mistake you need to close the app in the emulator and open it again. Hope this helps someone

RN is pretty new to me, anyone know any of the maintainers on here we can ping to have a look?

The implementation is definitely not stable, there is another issue here: https://github.com/facebook/react-native/issues/12830

Don’t really fancy using SQLite just to store a couple of integer values 😕

It is really frustrating. after few time of running the app. Aysnc AsyncStorage.getItem() stops working. I tried many hacky way to work around it. but after few times. its just don’t work.

AsyncStorage.getItem(key) .then((value) => { return value; })

I don’t know what will be solution in your case but this one worked for me

Firstely i was importing some componets from react-native like this import { Text, StyleSheet, TouchableHighlight, TextInput, } from ‘react-native’; import { AsyncStorage } from ‘react-native’;

and the AsyncStorage.getItem or AsyncStorage.setItem was not working, whatever code was there after AsunStorage was not running, so

I Modified my import like to this import { Text, StyleSheet, TouchableHighlight, TextInput, AsyncStorage } from ‘react-native’;

and now everything was working fine. I don’t know how it got resolved, but my AsyncStorage.setItem and AsyncStorage.getItem both was working fine

AsyncStorage.setItem(‘DEMO’, ‘false’);

try { let data = await AsyncStorage.getItem(“DEMO”); alert(data); } catch (error) {

    }

Me and my team of 3 RN developers had simultaneously gotten stuck in the same issue, so I wrote a simple FIleSystem based alternative to AsyncStorage named react-native-fs-store module, which is drop-in replacement of asyncStorage for very simple use cases. It also allows automatic switch to actual AsyncStorage in production. I hope it unblocks someone else as well.

I would say that just run react-native run-android again when you see issues pop up and they will be resolved. Also make sure that you don’t use implementations from other people when you do a google search for how to store and receive. The newest page on Asyncstorage in React Native docs shows how you should have those async functions (i.e. how to properly do it).

Just as an aside, you don’t actually have to close your emulator, or even your bundler/builder. Just long press the application (or go to the settings as per usual) open the settings and then “FORCE STOP” the application. If you then just re-open the application on the emulator, the localstorage is back and functioning again. Its been my sort-of-workaround for a while now.

Thanks for the hint. Seems like we need to close the Hot Reloading and close the app. Then open back and it work.

Even the custom Hooks (UseStorage) in React Native causing the same Problem.

import {useState, useEffect} from ‘react’; import {AsyncStorage} from ‘@react-native-community/async-storage’;

/* Hook for AsyncStorage */

const useStorage = (key, defaultValue) => { const [storage, updateStorageValue] = useState(defaultValue, ‘’); async function getStorageValue() { let value = key || defaultValue;

try {
  value = JSON.parse(await AsyncStorage.getItem(key)) || defaultValue;
} catch (e) {
} finally {
  updateStorageValue(value);
}

}

async function updateStorage(newValue) { try { if (newValue === null) { await AsyncStorage.removeItem(key); } else { const value = JSON.stringify(newValue); await AsyncStorage.setItem(key, value); } } catch (e) { } finally { updateStorageValue(newValue); } }

useEffect(() => { getStorageValue(); }, [getStorageValue]);

return [storage, updateStorage]; };

export default useStorage;

To fix the live reload - switching to async await worked for me.

Checked this SO Answer (and vote up 😃 )

@sandersjj try Expo SecureStorage. Alternatively, make sure you eject from expo, and then set and get a very simple standard key when your app loads. For some reason if you can get a full cycle in, it works perfectly (I thin k it has something to do with initializations and failures being blocking on the UI thread, but have no real clue why this works).

Hey Guys , I think I found the problem for myself ,it may seems stupid for you but what I did to work is just disable debug JS remotely and without logging my data inside AsyncStorage ,seems it’s working every time that I need the data , so the solution for me was to disable Debug JS Remotely on Chrome , then it works perfectly , hopefully it solves other problem .

after build APK again facing same issue. is there any other alternative solution?

@farzer yes, I’m able to build an APK using 0.57. This was never a problem for me in previous versions. The issue I had was with reading a value from asyncStorage once you reload the app using RR. The promise never got fulfilled. This was consistently failing for me. With 0.57, it works fine.

Also note that I did not upgrade from 0.55.4 to 0.57. I ran react-native init and copied my source code from the old folder. Not sure if that makes a difference.

but in 0.57, can you build your android apk? @apcjs @fikrikarim

@Khsed4, yes I have tested my app on 0.57 and it works fine. I have had the problem with previous versions consistently.

Can we update status of issue? 0.57 is released now, and from the changelog they mentioned AsyncStorage fix. Is the change solve this issue?

I face this issue while I run on this condition :

  • Remote JS debugging enable
  • run on an emulator with: npm run android
  • “react-native”: “~0.55.2”

this solution works for me:

  1. Stop remote JS debugging.
  2. close the app on the emulator.
  3. run with react-native run-android
  4. enable remote JS debugging to check the issue.

@goughjo02 same as well I tried but sadly my value is never returned hence I have switched to mongo and it works perfect now

That’s a Promise response. Try getItem(ITEMKEY).then(res => console.log(res))… or did you try that?

Okay I got into this problem when testing with android device, but so far there isn’t any issue with the iOS simulator.

Is this problem only exist in the development mode or is it also happening on production apps?

I guess this only happens in development right? Given that some of the comments before telling about the JS recompiling stuff?

What about redux-persist, is it good ?