awslabs / aws-mobile-appsync-sdk-android

Android SDK for AWS AppSync.
https://docs.amplify.aws/sdk/api/graphql/q/platform/android/
Apache License 2.0
105 stars 58 forks source link

App Sync SDK crashing with SQLiteBlobTooBigException #391

Closed IolandaRosa closed 2 years ago

IolandaRosa commented 2 years ago

Describe the bug App Sync SDK crashes in AppSyncMutationSqlCacheOperations.fetchAllRecords (AppSyncMutationSqlCacheOperations.java:97) due to SQLiteBlobTooBigException, and the issue seems to be related with memory handling issues. This is only happening on one device in the Play Console.

To Reproduce The crash appears to occur as soon as the user launches the app and the synchronization process begins.

Expected behavior The crash should be handled, and the SDK should log an error message that describes the issue.

Environment:

Device Information:

Additional context I'd like to know if anyone else has experienced this or a similar crash, and I'd like some clarification on what might be causing this (I'm guessing it's related to the size of user data) and how it could be handled in client applications.

The following is the crash log message:

Caused by: android.database.sqlite.SQLiteBlobTooBigException: at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow (Native Method) at android.database.sqlite.SQLiteConnection.executeForCursorWindow (SQLiteConnection.java:942) at android.database.sqlite.SQLiteSession.executeForCursorWindow (SQLiteSession.java:838) at android.database.sqlite.SQLiteQuery.fillWindow (SQLiteQuery.java:62) at android.database.sqlite.SQLiteCursor.fillWindow (SQLiteCursor.java:153) at android.database.sqlite.SQLiteCursor.getCount (SQLiteCursor.java:140) at android.database.AbstractCursor.moveToPosition (AbstractCursor.java:232) at android.database.AbstractCursor.moveToFirst (AbstractCursor.java:271) at com.amazonaws.mobileconnectors.appsync.AppSyncMutationSqlCacheOperations.fetchAllRecords (AppSyncMutationSqlCacheOperations.java:97) at com.amazonaws.mobileconnectors.appsync.PersistentOfflineMutationManager.fetchPersistentMutationsList (PersistentOfflineMutationManager.java:86) at com.amazonaws.mobileconnectors.appsync.PersistentOfflineMutationManager. (PersistentOfflineMutationManager.java:40) at com.amazonaws.mobileconnectors.appsync.AppSyncOfflineMutationManager. (AppSyncOfflineMutationManager.java:79) at com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient. (AWSAppSyncClient.java:209) at com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient. (AWSAppSyncClient.java:69) at com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient$Builder.build (AWSAppSyncClient.java:675)

mkabore commented 2 years ago

Hello, I have also encountered this same issue on Samsung Tab Active2, running Android 9. I am also using the SDK 3.3.1

crash log: android.database.sqlite.SQLiteBlobTooBigException: Row too big to fit into CursorWindow requiredPos=0, totalRows=3 at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method) at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:1060) at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836) at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62) at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:161) at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:149) at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:220) at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:259) at com.amazonaws.mobileconnectors.appsync.AppSyncMutationSqlCacheOperations.fetchAllRecords(AppSyncMutationSqlCacheOperations.java:97) at com.amazonaws.mobileconnectors.appsync.PersistentOfflineMutationManager.fetchPersistentMutationsList(PersistentOfflineMutationManager.java:86) at com.amazonaws.mobileconnectors.appsync.PersistentOfflineMutationManager.(PersistentOfflineMutationManager.java:40) at com.amazonaws.mobileconnectors.appsync.AppSyncOfflineMutationManager.(AppSyncOfflineMutationManager.java:79) at com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient.(AWSAppSyncClient.java:205) at com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient.(AWSAppSyncClient.java:68) at com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient$Builder.build(AWSAppSyncClient.java:664)

sunnyeverestek commented 2 years ago

Hello, I have also encountered this same issue on Mi A1, running Android 9. I am also using the SDK 3.3.1

Fatal Exception: android.database.sqlite.SQLiteBlobTooBigException: Row too big to fit into CursorWindow requiredPos=0, totalRows=1 at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(SQLiteConnection.java) at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:859) at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836) at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62) at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:149) at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:137) at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:220) at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:259) at com.amazonaws.mobileconnectors.appsync.AppSyncMutationSqlCacheOperations.fetchAllRecords(AppSyncMutationSqlCacheOperations.java:97) at com.amazonaws.mobileconnectors.appsync.PersistentOfflineMutationManager.fetchPersistentMutationsList(PersistentOfflineMutationManager.java:86) at com.amazonaws.mobileconnectors.appsync.PersistentOfflineMutationManager.(PersistentOfflineMutationManager.java:40) at com.amazonaws.mobileconnectors.appsync.AppSyncOfflineMutationManager.(AppSyncOfflineMutationManager.java:79) at com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient.(AWSAppSyncClient.java:209) at com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient.(AWSAppSyncClient.java:69) at com.amazonaws.mobileconnectors.appsync.AWSAppSyncClient$Builder.build(AWSAppSyncClient.java:675) at com.wowe.wowe.network.woweAppSync.WoweAppSyncClient.getKeyInstance(WoweAppSyncClient.java:143)

mikepschneider commented 2 years ago

Hello, It seems that the. default cursor size is 2MB so any row bigger than that will trigger this error.

There are some good discussions on stack overflow here and here and this post from google.

The best suggestion is to limit the row sizes and break up large rows into multiple smaller rows. But that may not be easy/possible for you if the app is already released without introducing some method of migrating existing user data.

The other suggestion is to override the cursor size by putting this code in your MainActivity before the AppSync/Amplify initialization:

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) {
   e.printStackTrace();
}

This should get around the error, at possible expense of app performance due to using more memory. But this is the risk of allowing unlimited sized blobs in your app.

Finally the google post above suggests migrating off of SQLiteCursor to the new android Paging Library. However this change would have to happen in the AppSync library so it's not something an app developer can change themselves. We will make a note of this for future development.

Please provide updates if this above suggestions resolve your issue.

IolandaRosa commented 2 years ago

The suggested override of the cursor size solved the issue.

Thanks