Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AsyncStorage Couldn't read row 0, col 0 from CursorWindow #12529

Closed
JAStanton opened this issue Feb 22, 2017 · 18 comments
Closed

AsyncStorage Couldn't read row 0, col 0 from CursorWindow #12529

JAStanton opened this issue Feb 22, 2017 · 18 comments
Labels
Bug Help Wanted :octocat: Issues ideal for external contributors. Resolution: Locked This issue was locked by the bot.

Comments

@JAStanton
Copy link
Contributor

JAStanton commented Feb 22, 2017

Description

When reading values that are too large using AsyncStorage on Android I run into this error:

I wrote a large value with AsyncStorage and later tried to read it, but it crashed.

BaseError: Couldn't read row 0, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
  at e (/node_modules/react-native/Libraries/Storage/AsyncStorage.js:423:22)
  at None (/node_modules/react-native/Libraries/Storage/AsyncStorage.js:416:71)
  at map ([native code])
  at errors (/node_modules/react-native/Libraries/Storage/AsyncStorage.js:416:51)
  at slicedToArray (/node_modules/react-native/Libraries/Storage/AsyncStorage.js:54:33)

Reproduction

It looks like on iOS we write to disk when the value is above a threshold and on Android we write to sqllite always.

let x = 'x';
while (x.length <= 3194304) {
  x = `${x}${x}`;
}
await AsyncStorage.setItem('@@GARBAGE@@', x); // works
const garbage = await AsyncStorage.getItem('@@GARBAGE@@'); // throws

Solution

In order for me to fix this I'll need to re-write AsyncStorage to write to disk instead of writing to sql. https://github.com/mvayngrib/react-native-safe-async-storage <--- this guys has the right idea but his code is super old and broken.

Additional Information

  • React Native version: 0.39.2
  • Platform: Android
  • Operating System: Samsung Galaxy S4
@brentvatne
Copy link
Collaborator

Hello! The react-native 0.29 is very out of date, can you try to repro this in the latest version?

@JAStanton
Copy link
Contributor Author

JAStanton commented Feb 24, 2017

Oh I'm sorry I meant to say 0.39.2 (Updated original post)

@davidck
Copy link

davidck commented Mar 11, 2017

Did you find a solution? I've ran into this today as well. Storing base64 encoded images in AsyncStorage... on RN 0.41

Same error returned from Android. Solution might have to start writing to disk instead.

@JAStanton
Copy link
Contributor Author

JAStanton commented Mar 12, 2017 via email

@agrass
Copy link

agrass commented May 18, 2017

Any recommended solution for this?? use react-native-fs?

@JAStanton
Copy link
Contributor Author

@agrass react-native-fs is a step in the right direction but it's quite slow. https://github.com/mvayngrib/react-native-safe-async-storage has the right idea but it just needs to be re-written. Another option is to try to read from disk, if you fail catch the failure, dump your state, (full or partial) and keep moving on. I do both approaches in my app. Garbage collect, catch the failure, as well as I using react-native-fs and an approach like react-native-safe-async-storage

@hramos hramos added the Icebox label Jul 25, 2017
@hramos
Copy link
Contributor

hramos commented Jul 25, 2017

Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!

If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:

  • Does the issue still reproduce on the latest release candidate? Post a comment with the version you tested.
  • If so, is there any information missing from the bug report? Post a comment with all the information required by the issue template.
  • Is there a pull request that addresses this issue? Post a comment with the PR number so we can follow up.

If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.

@hramos hramos closed this as completed Jul 25, 2017
@ThaJay
Copy link

ThaJay commented Oct 18, 2017

It's still an issue when trying to read something large from AsyncStorage.
Please consider an error on write instead.

also:
rt2zz/redux-persist#284
https://github.com/robwalkerco/redux-persist-filesystem-storage
(redux-persist is not needed to use redux-persist-filesystem-storage)

@skv-headless
Copy link
Contributor

@hramos It is not fixed for sure. Here is a small a explanation
https://stackoverflow.com/a/21432966/1410905.
Maybe it worth mentioning in the docs that max size for sqlite cursor is 2mb?

In docs said
On Android, AsyncStorage will use either RocksDB or SQLite based on what is available
would be great to know how to switch to RocksDB?

@hramos hramos reopened this Oct 25, 2017
@agrass
Copy link

agrass commented Nov 17, 2017

that limit of 2mb is for only one key/value document of the whole database?

@nevir
Copy link
Contributor

nevir commented Dec 12, 2017

per key/value

@stale
Copy link

stale bot commented Feb 10, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 10, 2018
@agrass
Copy link

agrass commented Feb 12, 2018

this still happening in newer versions right? I'm using RN 41

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 12, 2018
@nevir
Copy link
Contributor

nevir commented Feb 12, 2018

This is still a problem in the latest RN, AFAIK

@kelset
Copy link
Collaborator

kelset commented Feb 26, 2018

Can confirm that this is still an issue on 0.53 - basically is still valid what @skv-headless linked and the solution proposed by @ThaJay is prob the best 'workaround' at the moment.

Only side-issue with using redux-persist-filesystem-storage is that it's a bit 'massive', meaning that it would reset all the saved data if deployed as an update on an existing app (as is in our scenario). Any ideas on how to implement it in a non-destructive way? (writing a migration or something?)

@export-mike
Copy link

export-mike commented Jun 5, 2018

I've added this to a AsyncStorage.android.js file which I now use instead. I have a relatively large value to set.

Thanks to @robwalkerco

rt2zz/redux-persist#284 (comment)

/**
* @flow
*/

import RNFetchBlob from 'react-native-fetch-blob'

const DocumentDir = RNFetchBlob.fs.dirs.DocumentDir
const storagePath = `${DocumentDir}/persistStore`
const encoding = 'utf8'

const toFileName = (name: string) => name.split(':').join('-')
const fromFileName = (name: string) => name.split('-').join(':')

const pathForKey = (key: string) => `${storagePath}/${toFileName(key)}`

const AndroidFileStorage = {
  setItem: (
    key: string,
    value: string,
    callback?: ?(error: ?Error) => void,
  ) =>
    new Promise((resolve, reject) =>
      RNFetchBlob.fs.writeFile(pathForKey(key), value, encoding)
        .then(() => {
          if (callback) {
            callback()
          }
          resolve()
        })
        .catch(error => {
          if (callback) {
            callback(error && error)
          }
          reject(error)
        })
  ),
  getItem: (
    key: string,
    callback?: ?(error: ?Error, result: ?string) => void
  ) =>
    new Promise((resolve, reject) =>
      RNFetchBlob.fs.readFile(pathForKey(toFileName(key)), encoding)
        .then(data => {
          if (callback) {
            callback(null, data)
          }
          resolve(data)
        })
        .catch(error => {
          if (callback) {
            callback(error)
          }
          reject(error)
        })
  ),
  removeItem: (
    key: string,
    callback?: ?(error: ?Error) => void,
  ) =>
    new Promise((resolve, reject) =>
      RNFetchBlob.fs.unlink(pathForKey(toFileName(key)))
        .then(() => {
          if (callback) {
            callback()
          }
          resolve()
        })
        .catch(error => {
          if (callback) {
            callback(error)
          }
          reject(error)
        })
  ),
  getAllKeys: (
    callback?: ?(error: ?Error, keys: ?Array<string>) => void,
  ) =>
    new Promise((resolve, reject) =>
      RNFetchBlob.fs.exists(storagePath)
      .then(exists =>
        exists ? Promise.resolve() : RNFetchBlob.fs.mkdir(storagePath)
      )
      .then(() =>
        RNFetchBlob.fs.ls(storagePath)
          .then(files => files.map(file => fromFileName(file)))
          .then(files => {
            if (callback) {
              callback(null, files)
            }
            resolve(files)
          })
      )
      .catch(error => {
        if (callback) {
          callback(error)
        }
        reject(error)
      })
  ),
}

export default AndroidFileStorage

whilst AsyncStorage.ios.js

import {AsyncStorage} from 'react-native';
export default AsyncStorage;

@eassymo
Copy link

eassymo commented Sep 13, 2018

Still happening, ussing

"react": "16.4.0",
"react-native": "0.55.4",

@cpojer
Copy link
Contributor

cpojer commented Feb 15, 2019

This issue has been moved to react-native-async-storage/async-storage#10.

@cpojer cpojer closed this as completed Feb 15, 2019
@facebook facebook locked as resolved and limited conversation to collaborators Feb 15, 2020
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Feb 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Help Wanted :octocat: Issues ideal for external contributors. Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests