facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.9k stars 24.3k forks source link

AsyncStorage.getItem() doesn't seem to work #18372

Closed mrded closed 5 years ago

mrded commented 6 years ago

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');
});
react-native-bot commented 6 years ago

Thanks for posting this! It looks like your issue may refer to an older version of React Native. Can you reproduce the issue on the latest stable release?

Thank you for your contributions.

How to ContributeWhat to Expect from Maintainers

mrded commented 6 years ago

Updated react-native => 0.54.0

hjJunior commented 6 years ago

I'm getting the same issue, and I'm using 0.54.0 react-native version, so what I can do to solve this? is It the stable version ?

Actual Behavior

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

Environment

react: 16.3.0-alpha.1 react-native: 0.54.0 npm: 5.7.1 yarn: 1.3.2 windows: 10 emulator: Nexus 5 API P

xiaonull commented 6 years ago

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

hjJunior commented 6 years ago

@xiaonull did you mean I run npm install before run react-native run-android If is it, I have tried, even I tried to unistall and after install aplication on the device

arjasco commented 6 years ago

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.

Metroninja commented 6 years ago

Running into this issue sporadically on 0.54.2 on Android.

ohasy commented 6 years ago

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.

arjasco commented 6 years ago

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 😕

ohasy commented 6 years ago

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.

AleskiWeb commented 6 years ago

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)

lenoxzzedwin commented 6 years ago

@AleskiWeb that is very stressful. It's happening to me.

Some alternative?

almorak commented 6 years ago

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.

nahidmbstu commented 6 years ago

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........

hosseinalipour commented 6 years ago

the same issue, is it supposed to work with expo app or the issue is global?

ImadeLake commented 6 years ago

Hello the same here.....

"dependencies": { "expo": "^27.0.1", "react": "16.3.1", "react-native": "~0.55.2", "react-native-router-flux": "^4.0.0-beta.31" }

I don't understand why it's not working...

mgambati commented 6 years ago

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.

Jalalx commented 6 years ago

Any update on this?

C0dekid commented 6 years ago

Same issue, still waiting for a fix!

demarchisd commented 6 years ago

Same issue here.

finnfiddle commented 6 years ago

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

kkusanagi commented 6 years ago

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

ohasy commented 6 years ago

What about redux-persist, is it good ?

AleskiWeb commented 6 years ago

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.

apcjs commented 6 years ago

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

ilyabozhkov commented 6 years ago

@yashojha19, redux-persist is pretty bad. Too much code for nothing. There is "redux-offline" being a superstructure, more like opinionated interface to popular but unwieldy redux-persist. It doesn't make it better, just because redux-persist is bad at the core.

laukaichung commented 6 years ago
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.

kkusanagi commented 6 years ago

@stonecold123 I'm not sure how your script work. Just to confirm.

Did you add AsyncStorage class while import from React Native?

In order to use "await", did you add async function? Exp:

const fund = async (a)=>{

}; 

Did you close hot reloading? try close the app and start over again.

Remove the app and try build over again.

Should be work in some cases. For me, I just close app and open again.

laukaichung commented 6 years ago

@kkusanagi Yes, the code snippet is inside an async function, and I don't use hot reloading. I have now moved on to use a database to store the json objects. I can't get this specific method AsyncStorage.getItem() to work.

Mmisiek commented 6 years ago

Same here with iOS emulator.

fikrikarim commented 6 years ago

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?

thevikas commented 6 years ago

Having same problem while using expo client for my app on android. What happens is sqlite is not on the phone? Do I have to install sqlite with my app just so asyncstorage has a available storage?

Khsed4 commented 6 years ago

Have the same problem on 55 version , and if someone knows an alternative solution , let us know @react-native-bot

Poukai commented 6 years ago

Will this ever be fixed ?

Jalalx commented 6 years ago

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

Duckers commented 6 years ago

Same problem here. Basic usage of AsyncStorage doesn't behave as expected.

(Development setup, using a real iPhone X with live reload enabled)

banli17 commented 6 years ago

same problem here,after await AysncStorage.getItem() 's code never executes,0.65

componentWillMount = async ()=>{
    await AysncStorage.getItem('key')
  console.log('a')  // never execute

}
IYTEC commented 6 years ago

For me the problem started when I changed data in Asyncstorage, so I downloaded Asyncstorage data from the phone, open the data using sqlite db browser, to know what data was there and what data to remove, use Asyncstorage.removeItem to remove the specific data and restarted the application.

Hope it helps.

Khsed4 commented 6 years ago

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 .

talksik commented 6 years ago

@Khsed4 Will try this but your solutions seems reasonable as maybe the cache is going to chrome? I know an instance of socket.io treating both the chrome debugger and my emulator as two different clients, and this may be a similar problem.

verybluebot commented 6 years ago

exact same issue. AsyncStorage not saving in emulator, tested on IOS Environment:

  OS: macOS High Sierra 10.13.6
  Node: 10.6.0
  Yarn: 1.7.0
  npm: 6.1.0
  Watchman: 4.9.0
  Xcode: Xcode 9.4.1 Build version 9F2000
  Android Studio: 3.0 AI-171.4443003

Packages: (wanted => installed)
  react: 16.3.1 => 16.3.1
  react-native: ^0.55.3 => 0.55.3

I see this is super old issue, any known good walk arounds?

RuedigerMoeller commented 6 years ago

same here, debug mode emulator NO hot reload. seems timing dependent as on some machines it fails sometimes, on another machine it happens always

guitar9 commented 6 years ago

+1

Himujjal commented 6 years ago

Same issue here for react native 0.55.4.

What are some good AsyncStorage alternatives?

I will use the alternative until the fix is done. I used Realm but it is too complicated for simple usage.

talksik commented 6 years ago

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).

khuongdv commented 6 years ago

Same issue here. Either getItem async or sync ways it doesn't work as expected. Many time it hangs but no error thrown.

radjivF commented 6 years ago

Same problem here lol

silent-tan commented 6 years ago

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

goughjo02 commented 6 years ago

I had basic asyncstorage commands (getItem, setItem) working last night. Then today they stopped working, which is how I got here. I am now using redux persist and this is successfully persisting the state.

I have experienced the not-working of asyncstorage - but for some reason redux-persist is working as expected.

"react": "16.3.1",
"react-native": "~0.55.2",
"react-navigation": "^2.11.2",
"react-redux": "^5.0.7",
"redux": "^4.0.0",
"redux-persist": "^5.10.0",
Poukai commented 6 years ago

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.