Skip to content

[RichDocuments] downloadAs JSON key mismatch - file download fails with Collabora Online #17076

@chrip

Description

@chrip

Bug Description

When downloading/exporting documents from Collabora Online (richdocuments) in the Nextcloud Android app, the downloadAs JavaScript interface fails to parse the JSON message due to a key name mismatch between the JavaScript side and the Android side.

Root Cause

JavaScript side (mobile.js wraps the message):

{
  "MessageName": "downloadAs",
  "Values": {
    "url": "https://...",
    "format": "pdf"
  }
}

Android side (RichDocumentsEditorWebView.kt:133-149) expects:

{
  "URL": "https://...",
  "Type": "pdf"
}

The Android code uses downloadJson.getString("URL") and downloadJson.getString("TYPE") which fail because the actual JSON keys are lowercase (url, format).

Affected Code

  • app/src/main/java/com/owncloud/android/ui/activity/RichDocumentsEditorWebView.kt - RichDocumentsMobileInterface.downloadAs() method
  • Keys defined in companion object: URL = "URL", TYPE = "Type", FILENAME = "filename"

Reproduction Steps

  1. Open a document in Collabora Online via the Nextcloud Android app
  2. Click "Export as PDF" (or any other export/download format)
  3. The download silently fails (caught by JSONException catch block at line 148)

Expected Behavior

The file should download to the device's Downloads folder.

Proposed Fix

Update downloadAs() to handle both key naming conventions:

@JavascriptInterface
fun downloadAs(json: String?) {
    try {
        json ?: return
        val downloadJson = JSONObject(json)
        
        // Support both old and new key formats from Collabora Online
        val urlStr = downloadJson.optString("URL", downloadJson.optString("url", ""))
        if (urlStr.isEmpty()) return
        val url = urlStr.toUri()
        
        // Support both "Type" and "format" keys
        val type = downloadJson.optString("Type", downloadJson.optString("format", ""))
        
        when {
            "print".equals(type, ignoreCase = true) -> printFile(url)
            "slideshow".equals(type, ignoreCase = true) -> showSlideShow(url)
            else -> {
                val downloadFileName = downloadJson.optString("filename", fileName)
                downloadFile(url, downloadFileName)
            }
        }
    } catch (e: JSONException) {
        Log_OC.e(this, "Failed to parse download json message: $e")
    }
}

Key changes:

  1. Use optString() instead of getString() to avoid exceptions on missing keys
  2. Check for both "URL" and "url" (case-insensitive)
  3. Check for both "Type" and "format" (case-insensitive)
  4. Use ignoreCase = true for type comparison

Environment

  • Nextcloud Android app version: (check latest)
  • Collabora Online (richdocuments) server app version: 8.x+
  • This affects any Collabora Online version that sends url/format keys instead of URL/Type

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions