apache/cordova-plugin-file-transfer

open failed: ENOENT (No such file or directory)

hako2008 opened this issue · 2 comments

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

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above
uaza commented

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

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);