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

Row too big to fit into CursorWindow #617

Closed
1 task
daniel1up opened this issue May 31, 2021 · 4 comments
Closed
1 task

Row too big to fit into CursorWindow #617

daniel1up opened this issue May 31, 2021 · 4 comments
Labels
question General question about usage

Comments

@daniel1up
Copy link

Current behavior

Hello everyone,

I was using expo and I didn't faced any error while using AsyncStorage but after eject from Expo I have the issue:

Possible Unhandled Promise Rejection (id: 3):
Error: Row too big to fit into CursorWindow requiredPos=0, totalRows=1
convertError@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:138878:24
map@[native code]...

The error is showing when I call:
const appData = await AsyncStorage.getItem('@MakinaIMEAppDATA');

I just need to know why is working on Expo and why not in bare workflow, and what should i do to solve the issue.

Best regards

Expected behavior

To work fine exactly as in Expo managed.

Environment

  • Platforms tested:
    • Android
  • AsyncStorage version: ^1.15.5
  • React Native: ~0.63.4
@krizzu
Copy link
Member

krizzu commented Jul 19, 2021

Hey,

This error will be thrown if you try to read a data larger than 2MB at once (some sources say 1MB, but that's different per Android device). Expo uses AsyncStorage from React Native directly, so it has the same limitation. Are you use you use the same big data in both cases?

I suggest to either chop down data into smaller chunks (different entries) or use File system to deal with blobs.

@krizzu krizzu added the question General question about usage label Jul 19, 2021
@daniel1up
Copy link
Author

Hello @krizzu,

Thanks for the reply. Yes, I use the the same big data with Expo managed and Expo eject. I didn't understand why it was happening. But, I have solved this by increasing the size of CursorWindow, I found the solution in another ask by someone else. I am writing the solution below if is needed.

Tried to add these lines inside onCreate method in MainApplication.java:

try {
      Field field = CursorWindow.class.getDeclaredField("sCursorWindowSize");
      field.setAccessible(true);
      field.set(null, 100 * 1024 * 1024); //100MB
    } catch (Exception e) {
      if (BuildConfig.DEBUG) {
        e.printStackTrace();
      }
    }

Don't forget to import these classes:

import android.database.CursorWindow;
import java.lang.reflect.Field;

@kkureli
Copy link

kkureli commented Apr 4, 2022

Hello @krizzu,

Thanks for the reply. Yes, I use the the same big data with Expo managed and Expo eject. I didn't understand why it was happening. But, I have solved this by increasing the size of CursorWindow, I found the solution in another ask by someone else. I am writing the solution below if is needed.

Tried to add these lines inside onCreate method in MainApplication.java:

try {
      Field field = CursorWindow.class.getDeclaredField("sCursorWindowSize");
      field.setAccessible(true);
      field.set(null, 100 * 1024 * 1024); //100MB
    } catch (Exception e) {
      if (BuildConfig.DEBUG) {
        e.printStackTrace();
      }
    }

Don't forget to import these classes:

import android.database.CursorWindow;
import java.lang.reflect.Field;

thanks!

@mikekreeki
Copy link

If you have Expo managed project, you don't need to eject to be able to modify MainApplication.java with the code from above. You can write an Expo plugin that will do this on build time. I'll leave it here as someone might find it useful in the future.

{
  "expo": {
    "plugins": [
      "./plugins/withIncreasedAndroidCursorWindowSize"
    ]
  }
}
Object.defineProperty(exports, "__esModule", { value: true });

const config_plugins_1 = require("expo/config-plugins");
const addImports = require('@expo/config-plugins/build/android/codeMod').addImports;
const mergeContents = require('@expo/config-plugins/build/utils/generateCode').mergeContents;
const withMainActivity = require('expo/config-plugins').withMainActivity;

function injectCode(src) {
  return mergeContents({
    tag: 'withIncreasedAndroidCursorWindowSize-onCreate',
    src,
    newSrc: `
      try {
        Field field = CursorWindow.class.getDeclaredField("sCursorWindowSize");
        field.setAccessible(true);
        field.set(null, 100 * 1024 * 1024); //the 100MB is the new size
      } catch (Exception e) {
      }
    `,
    anchor: /super\.onCreate\(\w+\);/,
    offset: 1,
    comment: '//',
  });
}

const withIncreasedAndroidCursorWindowSize = (config) => {
  return withMainActivity(config, async (config) => {
    const src = addImports(
      config.modResults.contents,
      ['android.database.CursorWindow', 'java.lang.reflect.Field'],
      config.modResults.language === 'java',
    );

    if (config.modResults.language !== 'java') {
      throw new Error(
        'withIncreasedAndroidCursorWindowSize config plugin does not support kotlin MainActivity yet.',
      );
    }

    config.modResults.contents = injectCode(src).contents;

    return config;
  });
};

exports.default = (0, config_plugins_1.createRunOncePlugin)(withIncreasedAndroidCursorWindowSize, "withIncreasedAndroidCursorWindowSize");

zatteo added a commit to cozy/cozy-flagship-app that referenced this issue Nov 7, 2023
Default Android cursor size is 2MB so we can not store entries larger
than 2MB by default. But backup feature store quickly more than 2MB.

There are two main possibilities :
- AsyncStorage recommand to separate data in multiple entries and use
multiGet and multiSet
- increase sCursorWindowSize in MainApplication.java

I try here the second way now which looks like the "easy quick fix".

50MB seems a reasonable value here. 1000 pictures in mediasToBackup ~
330KiB

See
react-native-async-storage/async-storage#617 (comment)
and
https://react-native-async-storage.github.io/async-storage/docs/limits
zatteo added a commit to cozy/cozy-flagship-app that referenced this issue Nov 10, 2023
Default Android cursor size is 2MB so we can not store entries larger
than 2MB by default. But backup feature store quickly more than 2MB.

There are two main possibilities :
- AsyncStorage recommand to separate data in multiple entries and use
multiGet and multiSet
- increase sCursorWindowSize in MainApplication.java

I try here the second way now which looks like the "easy quick fix".

50MB seems a reasonable value here. 1000 pictures in mediasToBackup ~
330KiB

See
react-native-async-storage/async-storage#617 (comment)
and
https://react-native-async-storage.github.io/async-storage/docs/limits
zatteo added a commit to cozy/cozy-flagship-app that referenced this issue Nov 13, 2023
Default Android cursor size is 2MB so we can not store entries larger
than 2MB by default. But backup feature store quickly more than 2MB.

There are two main possibilities :
- AsyncStorage recommand to separate data in multiple entries and use
multiGet and multiSet
- increase sCursorWindowSize in MainApplication.java

I try here the second way now which looks like the "easy quick fix".

50MB seems a reasonable value here. 1000 pictures in mediasToBackup ~
330KiB

See
react-native-async-storage/async-storage#617 (comment)
and
https://react-native-async-storage.github.io/async-storage/docs/limits
paultranvan pushed a commit to cozy/cozy-flagship-app that referenced this issue Nov 17, 2023
Default Android cursor size is 2MB so we can not store entries larger
than 2MB by default. But backup feature store quickly more than 2MB.

There are two main possibilities :
- AsyncStorage recommand to separate data in multiple entries and use
multiGet and multiSet
- increase sCursorWindowSize in MainApplication.java

I try here the second way now which looks like the "easy quick fix".

50MB seems a reasonable value here. 1000 pictures in mediasToBackup ~
330KiB

See
react-native-async-storage/async-storage#617 (comment)
and
https://react-native-async-storage.github.io/async-storage/docs/limits
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question General question about usage
Projects
None yet
Development

No branches or pull requests

4 participants