Search code examples
ionic-frameworkcapacitor

How to open a PDF File from Blob with Ionic FileOpener and Capacitor


In my Ionic 5 project I have a PDF downloaded to the device (physical iPhone Pro, iOS simulators as well as Android devices). Transformed to Base64 and stored as .txt file. I'm retrieving the file as following:

const options = {
  path: path,
  directory: FilesystemDirectory.Data,
  encoding: FilesystemEncoding.UTF8
}

Filesystem.readFile(options)
  .then(result => {

    const jsonCast = JSON.parse(result.data)
    const blop: Blob = this.convertBase64ToBlob(jsonCast)
    resolve(blop)
})

The next step in my code is to get the URL of the Blob file:

const fileURL = URL.createObjectURL(blob)

Now tho with Ionic native's FileOpener, when I try to open the File by using:

this.fileOpener.open(blobURL, 'application/pdf')

I get the error message, that the File does not exist.

⚡️  [log] - fileURL:  blob:capacitor://localhost/ff4efd06-a313-44ce-b386-c756d456e72f   
2019-09-23 17:06:19.267144-0700 App[25791:19944973] Path parameter not encoded. Building file URL encoding it...
2019-09-23 17:06:19.267326-0700 App[25791:19944973] looking for file at blob:capacitor:/localhost/ff4efd06-a313-44ce-b386-c756d456e72f -- file:///
⚡️  [log] - Error opening file {"status":"9","message":"File does not exist"}  

What I am missing or what's a better approach to store a PDF File to the hard phone and retrieve then load and display it? I have tried pushing it to the Safari browser, but the plugin expects a https URL and catches as well.

Any help is highly appreciated.

PS: As mentioned in my question, I'm building the App with Capacitor. Therefore I'm limited as to what cordova plugins I'm able to use. Thank you for considering that in your help.


Solution

  • A blob url is an url only the app's WebView understands, you can't use that url to open it in another app.

    Instead of getting the file data and creating a blob url of it, just use getUri function to get the filesystem path of the file.

    Filesystem.getUri({
      directory: FilesystemDirectory.Data,
      path: path
    }).then((getUriResult) => {
      const path = getUriResult.uri;
      this.fileOpener.open(path, 'application/pdf')
    }, (error) => {
      console.log(error);
    });
    

    P.S. Since you are reading with encoding: FilesystemEncoding.UTF8, I assume you also used it to write, I don't think that will work, you shouldn't write it as base64 data without encoding.