-
Notifications
You must be signed in to change notification settings - Fork 866
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
Android AsyncStorage: "Error restoring state" for large datasets #284
Comments
There is some additional discussion around android limits here: #199 (comment) I do not have any solves off the top of my head, but I am open to ways we can be more resilient to storage limits. |
Hmm, I thought it might not be due to the size limit, as from my (limited) understanding, if But if this sounds exactly like the storage limit problem, no worries, I will look into some of the solutions specific to that limitation. |
Ahhh, I've just realised that it might be to do with the development platform I'm using (Exponent) running multiple apps from the same host app. So I guess that 6MB storage limit might be shared among all of their saved data. Will investigate further. |
@jamesisaac interesting, that could definitely be related. Do you have control over expanding the limit? Or possibly using other native modules like https://github.com/sriraman/react-native-shared-preferences |
Hi redux-persist/getStoredState: Error restoring data for key: pos Error: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. I've tried things like this in MainApplication.java - onCreate method: but it doesn't work for me @jamesisaac could you solve it ?? thanks in advance |
I have the same problem like @jorge627 anyone? |
I'm having a similar issue. I suspect we are hitting the max sqlite cursor window size on Android which is 2MB: http://stackoverflow.com/questions/21432556/android-java-lang-illegalstateexception-couldnt-read-row-0-col-0-from-cursorw |
@johnwayner so no way around this rather than reducing the size/data of a key or the |
@kenma9123 That's the assumption I'm working under. I have a data dump from a user that clearly demonstrates that the limit ( at least on their device) is 2MB. I'll be adding code to delete old data. If that doesn't keep key data under the limit, then I'll be splitting up my larger keys. It will result in more cross talk between reducers, which is unfortunate. |
@kenma9123 I've worked around this issue by creating my own storage for Android that uses the filesystem rather that AsyncStorage. Hopefully that will help others with this same issue. Expand to see the code
|
@robwalkerco wow great idea. I tried it and it works fine. You should create a repo for this and let it grow. |
@kenma9123 I've created a project on npm with a cleaned up version of the above code. Check out https://www.npmjs.com/package/redux-persist-filesystem-storage |
I just had the same issue and @robwalkerco 's lib fixed it - thanks a lot man! (btw I think this issue can be closed..?) |
Original issues: rt2zz/redux-persist#199 rt2zz/redux-persist#284 Converastions related to provided snippet: rt2zz/redux-persist#679 robwalkerco#7
Original issues: rt2zz/redux-persist#199 rt2zz/redux-persist#284 Converastions related to provided snippet: rt2zz/redux-persist#679 robwalkerco#7
Provide sample snippet which lets app migrate data previously stored in `AsyncStorage` to `redux-persist-filesystem-storage` Original issues: rt2zz/redux-persist#199 rt2zz/redux-persist#284 Converastions related to provided snippet: rt2zz/redux-persist#679 robwalkerco#7
Provide sample snippet which lets app migrate data previously stored in `AsyncStorage` to `redux-persist-filesystem-storage` Original issues: rt2zz/redux-persist#199 rt2zz/redux-persist#284 Converastions related to provided snippet: rt2zz/redux-persist#679 robwalkerco#7
The motivation that makes this important to do now is the storage limits imposed by RN's AsyncStorage on Android. In particular, on Android the open-source RN uses a backend called AsyncSQLiteDBStorage (it prefers one called AsyncRocksDBStorage if present, but the implementation of that one seems to be internal to Facebook). In that backend: * A limit of 6 MiB is imposed on the size of the entire database. This is a choice made inside RN; see `mMaximumDatabaseSize` in upstream's ReactDatabaseSupplier.java . * The system's SQLite library retrieves data in windows of, by default, 2 MiB, and rows larger than that will cause an error. The backend stores each key-value pair as a row, and redux-persist gives it each top-level subtree of the state into a key-value pair; so when one top-level subtree goes over 2 MB or so, it fails, discarding the whole persisted store: rt2zz/redux-persist#284 The `users` state subtree for chat.zulip.org now comes to a little over 1.8M characters, so we must be approaching this limit. (This also means it's getting encoded as bytes reasonably efficiently, presumably as UTF-8.) Looking at Android docs, it looks like a sufficiently determined Android app could use `SQLiteCursor#setWindow` to change this size; but the code that'd have to do that is deep inside RN, so even doing that as a quick hack would take some work. On iOS, by contrast, AsyncStorage uses a simple custom key-value store with large values stored out of line (see RCTAsyncLocalStorage.m .) That one doesn't seem to have any such limitations. A library "redux-persist-transform-compress" is intended to solve this problem; but it implements the compression algorithm in JS, which makes it slow and adds serious lag to the app. So we don't use that. Instead, implement a native module to do the compression in Java, and provide a wrapper for RN's AsyncStorage to use it. Note that we can't do this with redux-persist's "transformer" concept, because transformers don't support async operations. Loading and compressing state can take enough time to cause frame drops, so we need it to happen async. [greg: expanded the explanation / research about storage limits; also deactivated the actual invocation of CompressedAsyncStorage, pending the needed fallback logic.]
@robwalkerco Thanks you saved my day. |
For me, this solution worked.
Also import these on top of the
|
@shehzadosama thanks for the solution, however this will lead to |
This library has been working perfectly for me with smaller size state trees, but trying to use it on bigger ones I'm running into these errors when relaunching the app:
Specifically, I'm trying to store a lot of data from a server locally. To give an idea of the size, running
JSON.stringify(payload).length
gives2368916
, so it looks like it should be within the 6MB limit.I'm not having any of the performance issues described in #185 either - the app runs fairly smoothly (perhaps because writes are used sparingly). It's just a case of closing the app and reopening it leading to this error when it tries to rehydrate.
The text was updated successfully, but these errors were encountered: