DEV Community

Cover image for Upgrading from Capacitor 2 in 2024 - Part 2: Files
Gerhard for Reconcept

Posted on

Upgrading from Capacitor 2 in 2024 - Part 2: Files

Finally, we could start with upgrading the plugins from Cordova to Capacitor.

The first plugins we chose to upgrade all had to do with handling files. In the application you can attach files to your portfolio, which of course can be chosen from the device.

We had several plugins to manage this in Cordova, even specific ones for Android and iOS:

  • @ionic-native/file-chooser (android)
  • @ionic-native/file-picker (iOS)
  • @ionic-native/image-picker (for iOS & android)

In Capacitor, these were all replaced using Capacitors’ Filesystem plugin. This plugin had all the features we needed, and works basically the same, by returning a path to where the file was located on the devices.

Troubles ahead

The trouble began when we wanted to upload the selected file to our back-end, to connect them to the portfolio. We use S3 as storage, and have written code that uses the JavaScript File interface to upload the file. But the plugins all return a string to the file on the device, not the actual file itself.

We had a different Cordova plugin to handle this @ionic-native/file, that added a function called resolveLocalFileSystemURL. This returns a JavaScript File from the given path, which we used in our code to upload.

Here again, Capacitors’ Filesystem came to the rescue. The readFile function returns a base64 encoded string from the file contents. Then using some ‘inspiration’ from stack overflow, we created a Blob from which we can create the File instance we need for our existing code.

This all made sense in theory, but when executing the code we found that the contents of the file were always empty.
We went deep into the plugin’s code to see what was going on, and we saw that the readFile function uses the FileReader from the browser the app is running in But because the Capacitor plugins run outside of the Angular zone, we’d get a different instance for this FileReader than the one we get from ZoneJS to upload the file to the S3 storage!.

Patching FileReader

We found some help on the internet, and now we patch the FileReader constructor to always use the instance used by ZoneJS (if present). Lovely stuff.
The last plugins concerning files were the FileOpener and PhotoViewer.

The FileOpener requests the OS for an app to open the file, and we found that the plugin from the Capacitor community @Capacitor-community/file-opener was a near drop-in replacement for the Cordova version.
For the photo viewer, we also chose a community plugin: @Capacitor-community/photoviewer. This one actually had quite a few installation steps, because the plugin is written in Kotlin, but the steps were clear to follow and the plugin worked immediately.

The upgrading of the file handling in the app had some up’s and downs. Some plugins were easily replaced, but the whole FileReader issue caused a lot of headaches. Some luck was needed to realise the problem with the multiple instances, but the fix/hack works like a dream/nightmare.

If all plugins cause problems like this, we might have a bumpier road ahead of us then we’d like.

Top comments (0)