4

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.

David Seek
  • 16,783
  • 19
  • 105
  • 136

1 Answers1

6

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.

tobias47n9e
  • 2,233
  • 3
  • 28
  • 54
jcesarmobile
  • 51,328
  • 11
  • 132
  • 176
  • Okay well. That all makes sense. Just the last point does not. `you shouldn't write it as base64 data without encoding`. Well I thought I did not. I used UTF8 encoding? And you're right. The PDF doesnt work. I just shows a file, with the name and the file size. I assume as corrupt PDF file? – David Seek Sep 26 '19 at 19:41
  • I had removed the UTF8 encoding from all writing/loading options, but now my console is just swamped with `Unable to save file`. Can you possibly provide a writing example as well, please? I'm so close to get this finally done... Already stuck in the 2nd week. – David Seek Sep 26 '19 at 19:46
  • It has to be proper base64 string to write it without encoding – jcesarmobile Sep 26 '19 at 20:42
  • Well it looks like proper base64 to me, I'm using `onloadend` `.result` of `const reader = (new FileReader() as any)._realReader` – David Seek Sep 26 '19 at 21:12
  • This is basically how I create the base64 from blob: https://stackoverflow.com/a/18650249/5896501 – David Seek Sep 26 '19 at 21:41
  • I have been further researching and found, that I need to use: `const dataUrl = reader.result; const base64 = dataUrl.split(',')[1]`, but here I still get: `Error: Unable to save file` – David Seek Sep 26 '19 at 21:49
  • I got it working! Thank you so much for guiding me into the correct direction! – David Seek Sep 26 '19 at 22:08
  • I'll wait out the bounty period tho. Just in case anyone else has any useful tips. But you've answered the question properly so I'll award you bounty and answer-checkmark by the end of the period. – David Seek Sep 26 '19 at 22:22
  • I have a similar issue opening a PDF file returned from an API request as raw binary. I convert it to a blob, write the file using FileSystem.writeFile, get the uri using FileSystem.getUri, then try and open it. Can you please explain where the library "this.fileOpener" comes from? The only "solution" I found, which is throwing a typeError (TypeError: undefined is not an object (near '...})...') (anonymous function) — reports.js:303 promiseReactionJob" is "cordova.plugins.fileOpener2". If anyone can give me any tips on getting the PDF to open I would appreciate it! Thanks – user2115620 May 11 '20 at 08:59
  • Thanks, buddy! You helped me a lot! I think Ionic/Capacitor could provide a better example on how to open a pdf file. – Wesin Alves Nov 16 '21 at 10:59