Android集成Firestore报错:Row too big to fit into CursorWindow
我在Android项目中使用Firebase Firestore存储自定义数据类,已按照官方教程的添加数据步骤操作,但出现以下错误:
SQLiteQuery 异常
E/SQLiteQuery: exception: Row too big to fit into CursorWindow requiredPos=0, totalRows=9; query: SELECT overlay_mutation, largest_batch_id FROM document_overlays WHERE uid = ? AND collection_path = ? AND largest_batch_id > ?
数据类及转换方法(Diary.kt)
data class Diary( val id: String = "", val account: String = "", val title: String = "", val content: String = "", val imageUri: String? = null, val likesCount: Int = 0, val isLiked: Boolean = false, val comments: List<String> = listOf(), val createdTime: Long = 0L, val updatedTime: Long? = null, val isThumbnailExist: Boolean = false ) { fun mappingForFireStore(): HashMap<String, Any?> { return hashMapOf( "id" to id, "account" to account, "title" to title, "content" to content, "imageUri" to imageUri, "likes_count" to likesCount, "is_liked" to isLiked, "comments" to comments, "created_time" to createdTime, "updated_time" to updatedTime, "is_thumbnail_exist" to isThumbnailExist ) } }
保存到Firestore的函数(Save-To-FireStore func.kt)
private fun asyncTestFirebase() { val data1 = Diary( id = UUID.randomUUID().toString(), account = idInput.value!!.trim(), title = "My second data", content = "test data.", createdTime = Calendar.getInstance(Locale.getDefault()).time.time ).mappingForFireStore() db.collection("diaries") .add(data1) .addOnSuccessListener { documentReference -> Log.d("Haha", "DocumentSnapshot added with ID: ${documentReference.id}") } .addOnFailureListener { error -> Log.d("OMG", error.stackTraceToString()) } }
我没有直接存储图片,也未使用Cursor或Field,数据量也未超过1MB,但仍遇到该问题,请问如何解决才能成功将数据保存到Firestore?
AndroidRuntime 错误日志
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.movingroot.simpleproject, PID: 1616
java.lang.RuntimeException: Internal error in Cloud Firestore (24.2.2).
at com.google.firebase.firestore.util.AsyncQueue.lambda$panic$3(AsyncQueue.java:539)
at com.google.firebase.firestore.util.AsyncQueue$$ExternalSyntheticLambda3.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: java.lang.RuntimeException: android.database.sqlite.SQLiteBlobTooBigException: Row too big to fit into CursorWindow requiredPos=0, totalRows=9
at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor.lambda$executeAndReportResult$1(AsyncQueue.java:330)
at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$$ExternalSyntheticLambda0.run(Unknown Source:4)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$DelayedStartFactory.run(AsyncQueue.java:234)
at java.lang.Thread.run(Thread.java:920)
Caused by: android.database.sqlite.SQLiteBlobTooBigException: Row too big to fit into CursorWindow requiredPos=0, totalRows=9
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:1003)
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:145)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:132)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:238)
at android.database.AbstractCursor.moveToNext(AbstractCursor.java:287)
at com.google.firebase.firestore.local.SQLitePersistence$Query.forEach(SQLitePersistence.java:493)
at com.google.firebase.firestore.local.SQLiteDocumentOverlayCache.getOverlays(SQLiteDocumentOverlayCache.java:149)
at com.google.firebase.firestore.local.LocalDocumentsView.getDocumentsMatchingCollectionQuery(LocalDocumentsView.java:365)
at com.google.firebase.firestore.local.LocalDocumentsView.getDocumentsMatchingQuery(LocalDocumentsView.java:266)
at com.google.firebase.firestore.local.QueryEngine.appendRemainingResults(QueryEngine.java:259)
at com.google.firebase.firestore.local.QueryEngine.performQueryUsingRemoteKeys(QueryEngine.java:175)
at com.google.firebase.firestore.local.QueryEngine.getDocumentsMatchingQuery(QueryEngine.java:85)
at com.google.firebase.firestore.local.LocalStore.executeQuery(LocalStore.java:844)
at com.google.firebase.firestore.core.SyncEngine.initializeViewAndComputeSnapshot(SyncEngine.java:214)
at com.google.firebase.firestore.core.SyncEngine.listen(SyncEngine.java:207)
at com.google.firebase.firestore.core.EventManager.addQueryListener(EventManager.java:104)
at com.google.firebase.firestore.core.FirestoreClient.lambda$listen$7$com-google-firebase-firestore-core-FirestoreClient(FirestoreClient.java:177)
at com.google.firebase.firestore.core.FirestoreClient$$ExternalSyntheticLambda3.run(Unknown Source:4)
解决方案
1. 升级Firestore依赖版本
当前使用的Firestore 24.2.2版本存在本地SQLite缓存的已知bug,建议升级到最新稳定版。在Module级别的build.gradle中更新依赖:
implementation 'com.google.firebase:firebase-firestore:24.10.0' // 替换为最新版本号
2. 清除Firestore本地缓存
若升级版本后问题仍存在,可手动清除本地缓存,调用时机建议放在App启动初期(如Application的onCreate方法),且确保此时无活跃的Firestore监听:
db.clearPersistence()
3. 清空本地缓存堆积
该错误多由Firestore本地SQLite缓存的document_overlays表行数据过大导致,可能是之前有大量未同步的修改堆积。可尝试卸载重装App,清空本地缓存后再测试。
4. 拆分批量数据
若业务需要批量添加数据,避免一次性提交过多,拆分小批量操作,减少本地缓存的压力。
内容的提问来源于stack exchange,提问作者MovingRoot Lee

