apache / cordova-plugin-file-transfer

Apache Cordova File Transfer Plugin
https://cordova.apache.org/
Apache License 2.0
595 stars 888 forks source link

open failed: ENOENT (No such file or directory) #376

Open hako2008 opened 7 months ago

hako2008 commented 7 months ago

Bug Report

Hi ! I'm currently unable to make the plugin work properly.

Problem

FileTransfer.download is failing with an error code 1

{
"code":1,
"source":"https://mydomain.com/uploads/profiles/passengers/15/a5dfc010d9d4937820d9663a23a931eefaf51dcb.jpg",
"target":"file:///data/user/0/com.myapp.name/images/profile/a5dfc010d9d4937820d9663a23a931eefaf51dcb.jpg",
"http_status":200,
"body":null,
"exception":"/data/user/0/com.myapp.name/images/profile/a5dfc010d9d4937820d9663a23a931eefaf51dcb.jpg: open failed: ENOENT (No such file or directory)"
}

The weird thing is sometimes work just fine, the same code the same app works fine sometimes gives the error. The weirdest thing is i have another app with the same code it works just fine.

What is expected to happen?

What does actually happen?

When i store the file directly in the app private directory (cordova.file.applicationStorageDirectory + newNam) without trying create sub directories 'images/profile' (cordova.file.applicationStorageDirectory+'images/profile/' + newNam) its work fine

Information

when i tried to create the directory using the file system sometimes create normally in another time can't created and gives error code : 12

function writeFile() {
        console.log(cordova.file.applicationStorageDirectory);
        window.resolveLocalFileSystemURL(cordova.file.applicationStorageDirectory, function(fileSystem){
            var entry = "";
                entry = fileSystem;
           console.log(entry);
            entry.getDirectory("images/profile", {
                create: true
            }, onGetDirectorySuccess, onGetDirectoryFail);
        }, onError);
}

function onError(e) {
        console.error({"onError":e});
};

function onGetDirectoryFail(dir) {
        console.log({"directory does not created!!!!!":dir});
};

function onGetDirectorySuccess(dir) {
        console.log({"directory created.":dir});
 };

i have the WRITE_EXTERNAL_STORAGE permission

<uses-permission android:maxSdkVersion="32" android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

even i asking for the permission of the app hasn't

var permissions = cordova.plugins.permissions;
permissions.checkPermission(permissions.WRITE_EXTERNAL_STORAGE, function (status) {
    if (!status.hasPermission) {
        console.error('hasPermission no STORAGE permissions: ');
        console.log(status);
        requestPermissions();
    }
}, function (error) {
    console.error('Error checking permissions: ' + error);
});

function requestPermissions() {
    permissions.requestPermission(
        permissions.WRITE_EXTERNAL_STORAGE,
        function (status) {
            if (!status.hasPermission) {
                console.error('Permission not granted');
            }else{
                console.log({'hasPermissionWRITE_EXTERNAL_STORAGE':status});
            }
        },
        function (error) {
            console.error('Error requesting permissions: ' + error);
        }
    );
}

Command or Code

var uri = encodeURI("https://mydomain.com"+response['success']['img']);
var newNam = response['success']['img'].substring(response['success']['img'].lastIndexOf('/')+1);
console.log('cordova.file.applicationStorageDirectory : '+cordova.file.applicationStorageDirectory);
console.log('cordova.file.dataDirectory : '+cordova.file.dataDirectory);
fileTransfer.download(
    uri,
    cordova.file.applicationStorageDirectory+'images/profile/' + newNam,
    function(entry) {
        EmptyDir(cordova.file.applicationStorageDirectory+'images/profile/',newNam);
        console.log("download complete: " + entry.toURL());

    },
    function(error) {                                    
        console.log('download error message:');
        console.log(error);                                
    },
    false,
    {
        headers: {
            "Authorization": "Basic dGVzdHV23ZXNuYW1lOnSlc3RwYXN5029yZA=="
        }
    }
);

Environment, Platform, Device

Cordova @12 cordova-android@12.0.1 cordova-plugin-file-transfer 2.0.1-dev cordova-plugin-file 8.0.1 android-targetSdkVersion 33

Version information

Checklist

uaza commented 1 month ago

@hako2008 I have encountered the same problem, have you found a solution?

breautek commented 1 month ago

I don't think recursive directory creates are supported.

e.g. you must first check if images is created and if not, create the directory, then check for profile directory and create it if it doesn't exist.

Directly attempting to create (or get) images/profile will fail if images is not already created. Likewise, attempting to download to a directory whose path isn't available will also fail. This is noted here

In otherwords:

entry.getDirectory("images/profile", {
                create: true
            }, onGetDirectorySuccess, onGetDirectoryFail);

this is unsafe unless images directory is guaranteed to exist which is an unsafe assumption for applicationStorageDirectory directory. It needs to be split into 2 getDirectory calls, cascaded into their respective callbacks.

entry.getDirectory("images", {
  create: true
}, (imagesDir) => {
  imagesDir.getDirectory("profile", {
    create: true
  }, onGetDirectorySuccess, onGetDirectoryFail);
}, onGetDirectoryFail);