apache / cordova-plugin-file

Apache Cordova File Plugin
https://cordova.apache.org/
Apache License 2.0
740 stars 757 forks source link

Getting error code 2 when saving pdf file on Android 13 #612

Closed emilkitua closed 6 months ago

emilkitua commented 6 months ago

Bug Report

Getting error code 2 when saving pdf file on Android 13

Problem

I have an application that saves files downloaded from web to the phone. when upgrading to android 13, it doesnot work. All changes prior that worked on both android 11 and 12. Also permission requests is not shown, although i am aware of the permission changes in Android 13. just not sure if it is checked in the background

What is expected to happen?

I expected the file to be saved on the phone, and i can trigger google drive to open the file so the user can view the pdf file.

What does actually happen?

I am getting error { "code": 2 } i.e SECURITY_ERR when i try to create the file. Looking it up, it relates to permission issue

Information

my current code to save the file ` async saveImageToDevice(folderpath,filename,content,contentType){

const loading = await this.loadingCtrl.create();
await loading.present();

//Determine a native file path to save to
let filePath = '';
if(this.plt.is('android')) {
  filePath = this.file.externalRootDirectory + "/Download";
} else if(this.plt.is('ios')) {
  filePath = this.file.documentsDirectory;
} else {
  this.file.cacheDirectory
}
// let filePath = (this.plt.is('android')) ? this.file.externalRootDirectory : this.file.cacheDirectory;

//Write the file
if (this.plt.is("pwa")) {
  const url = window.URL.createObjectURL(
    content
  );
  const link = window.document.createElement("a");
  link.href = url;
  link.setAttribute("download", filename);
  window.document.body.appendChild(link);
  link.click();
  link.remove();
  await loading.dismiss();
} else {
  return this.file.writeFile(
    filePath,
    filename,
    content,
    { replace: true}
  ).then((success)=> {
    loading.dismiss();
    this.logging.log("File created Succesfully" + JSON.stringify(success))
    this.alertMessage('File downloaded to device. Check downloads for the receipt file.', filename)
  })
  .catch((err) => {
    loading.dismiss();
    this.logging.error("Error creating file: " + JSON.stringify(err));
    this.notification.showAlert("Error","Error creating file: " + JSON.stringify(err));
    throw err;  //Rethrow - will be caught by caller
  });
}

}`

Version information

Ionic:

Ionic CLI : 6.19.1 (C:\Users....\AppData\Roaming\npm\node_modules\@ionic\cli) Ionic Framework : @ionic/angular 6.7.5 @angular-devkit/build-angular : 14.2.13 @angular-devkit/schematics : 14.2.13 @angular/cli : 14.2.13 @ionic/angular-toolkit : 6.1.0

Cordova:

Cordova CLI : 11.0.0 Cordova Platforms : android 12.0.1 Cordova Plugins : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 5.0.0, (and 19 other plugins)

Utility:

cordova-res : 0.15.4 native-run (update available: 1.7.2) : 1.6.0

System:

Android SDK Tools : 26.1.1 (C:\Users...\AppData\Local\Android\Sdk) NodeJS : v16.14.2 (C:\Program Files\nodejs\node.exe) npm : 8.5.0 OS : Windows 10

Package.json

{ ... "dependencies": { ... "@awesome-cordova-plugins/file": "^6.4.0", ... }, "devDependencies": { ... "cordova-plugin-file": "^8.0.0", ... }, "description": "An Ionic project", "cordova": { "plugins": { ... "cordova-plugin-file": { "ANDROIDX_WEBKIT_VERSION": "1.4.0" } }, "platforms": [ "android" ] } }

Checklist

breautek commented 6 months ago

Filesystem access to external storage since scoped storage is limited to media files, which only include Images, Videos, and Audio files.

Any other type of file including document files cannot be read or written to external storage directly via the filesystem. The quirks of using this plugin with the external filesystem is documented here.

In short, if you must write to the external Downloads directory and you're working with PDF or other document files, then you will have to migrate to a plugin that interfaces with the native MediaStore APIs instead. There's a few third-party plugins in the cordova ecosystem. Even if you're exclusively working with media files, migrating to a MediaStore interfaced plugin is still a good idea because external filesystem support via File APIs is completely unsupported on API 29 devices, and support was only introduced in API 30.

Note that these limitations only applies to the external filesystem. If you have no need to share this document file with other apps, then you can use the app's internal filesystem (e.g. cordova.file.dataDirectory) to read/write and manage your document files.

I'm closing this issue because because there is nothing actionable by Cordova to address this issue.