GeezerVison is showing github.com — Thumbnails duplications, missing thumbnails and files failing to download · Issue #17918 · nextcloud/android
Thumbnails duplications, missing thumbnails and files failing to download #17918Description⚠️ Before posting ⚠️
- This is a bug, not a question or an enhancement.
- I've searched for similar issues and didn't find a duplicate.
- I've written a clear and descriptive title for this issue, not just "Bug" or "Crash".
- I agree to follow Nextcloud's Code of Conduct.
Steps to reproduce
- Open Discord
- Click share file
- In share popup choose Nextcloud
- Navigate to folder full of images
Expected behaviour
- All thumbnails load(preferably from cache)
- Same files do not appear more than once
- Files can be shared
Actual behaviour
- Some thumbnails never work
- Some files appear twice
- Some files fail to sync/share
Android version
16
Device brand and model
Samsung Galaxy S10+
Stock or custom OS?
Custom (explain in "additional information")
Nextcloud android app version
35.0.2
Nextcloud server version
26
Using a reverse proxy?
Yes
Android logs
No response
Server error logs
Additional information
My OS is lineage OS. There is no file at storage/emulated/0/data/nextcloud.log.
I had these 3 issues for a while. I suspect that they are at least partially because of me using adb to just pull and push all the files when changing phone, but some of these issues like broken thumbnails were older than that. I tasked Deepseek with debugging these issues and it found couple of problems with both with the state of files on my phone and code itself. In particular, it seems there is a race condition that causes duplications in file database and wrong thumbnail size reporting which breaks thumbnails for files smaller than the thumbnail. I am not going to pretend to be experienced in Java nor your codebase, but I've pushed commit that fixes code issues to my fork. It's fairly short so you might find it useful, but take it with grain of salt(claude had some concerns on the quality of this fix). funmaker@c8c7f75
Here is a more in detail description from Deepseek agent:
Investigated all three against the live device, server, app database, and source.
Root causes
1. Duplicate files in /xD/reaction/
The file database itself contained duplicate rows, not the server. For example:
_id 1800 /xD/reaction/001.jpg remote_id 00427388...
_id 2086 /xD/reaction/001.jpg remote_id 00427388...
There were 354 duplicate-path groups (580 rows for 292 files in /xD/reaction/).
I reproduced the creation mechanism: forcing two concurrent queryChildDocuments() calls on the same stale folder started two RefreshFolderOperations at once. Both took a database snapshot before either saved, both saw the file as “new”, and both inserted it. FileDataStorageManager.saveFolder() does a check-then-insert without serialization, so it is a race.
2. Broken/missing thumbnails
Two bugs:
- DocumentsStorageProvider.openDocumentThumbnail() returned a generated PNG thumbnail but told the caller its length was file.fileLength — the original file size. Small images often have thumbnails larger than the original, so the thumbnail was truncated and failed to decode. Example: /xD/reaction/001.jpg is 13,645 bytes, but its generated thumbnail file was 60,533 bytes; only 13,645 bytes were exposed.
- DiskLruImageCacheFileProvider.getParcelFileDescriptorForOCFile() called Files.createFile() and only wrote the bitmap inside the same try. If the cache file already existed, createFile() threw and the write was skipped, leaving stale/old thumbnail data forever. Cache files were also keyed only by base filename, so equal filenames in different folders collided.
- Additionally ThumbnailsCacheManager.containsBitmap() dereferenced the disk cache before its async initialization finished, and addBitmapToCache() silently dropped images during startup, so first thumbnails were not cached.
3. /xD/reaction/111665930_..._n.png cannot be opened/shared
This was a device MediaProvider ownership problem, not a Nextcloud logic bug.
The file was registered in MediaProvider’s external.db as:
owner_package_name = com.android.shell
while the app is com.nextcloud.client. The app therefore got EACCES when opening/replacing it. 352 of 593 files under the Nextcloud media directory had the same wrong owner. Because the DB row had an empty etag, DocumentOpener also tried to re-download it; the HTTP download succeeded, but Files.move(..., REPLACE_EXISTING) then failed with EACCES, and opening the existing local file failed too.
Changes made
Source changes in the working tree:
- DocumentLister.kt
- Deduplicates listed/search results by remoteId / decrypted path.
- Coalesces concurrent folder reload jobs per document so repeated queryChildDocuments() calls do not start parallel refreshes.
- FileDataStorageManager.java
- Serializes saveFolder() through a process-wide lock, eliminating the check-then-insert race that created duplicate rows.
- DocumentsStorageProvider.kt
- Returns the actual thumbnail file size via descriptor.statSize instead of the original document size.
- DiskLruImageCacheFileProvider.java
- Always overwrites the generated thumbnail, uses a unique thumbnail filename (remoteId), and reports the real file.
- ThumbnailsCacheManager.java
- containsBitmap() now waits for disk-cache initialization and is null-safe.
- addBitmapToCache() waits for initialization instead of silently dropping thumbnails.
Device fixes applied
- Removed 354 duplicate filelist rows and reparented any affected children. Verified PRAGMA integrity_check = ok; /xD/reaction/ now returns 292 rows, no duplicates.
- Backup left at /data/local/tmp/filelist-before-dedupe.db.
- Repaired MediaProvider ownership for all 593 Nextcloud media files (com.android.shell / old ownership → com.nextcloud.client), preserving the files_update trigger and restarting MediaProvider.
- Deleted and re-downloaded the originally failing 111665930_..._n.png.
Verified content read now succeeds for:
- /xD/reaction/001.jpg — 13,645 bytes
- /xD/reaction/111665930_316871886117476_1713782649053830776_n.png — 92,032 bytes
- /xD/reaction/1708011767812109.jpg — 39,491 bytes
Status / caveat
The device-side duplicate cleanup and MediaProvider repair take effect immediately. The source fixes for duplicate prevention and thumbnails require rebuilding/reinstalling the APK; this environment has no Android SDK/AGP cache, so I could not compile or install the patched build here. The changes are uncommitted for human review as required by the project’s AI contribution policy.
Build · DeepSeek V4.1 Flash · 37m 33s · 47.8 tok/s
After these devices fixes and rebuilding the app for my device all the issues were resolved. MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|