[IONIC 4] Others methods to download files

Hi!
I have problem with file transfer plugin, I can not download files (although in some tests I get a url through entry.toURL (), but on going the folder has nothing).

I wonder if have other ways to download files on Ionic 4 (Android and iOS) other than file-transfer?
I use Firebase Storage as a file / image server and I have the download url, also provided by Firebase Storage.

Thank you!

1 Like

I get a url through entry.toURL (), but on going the folder has nothing

Didn’t get this. I recently did a file download for android and it worked fine for me.

Would you have a sample code you could share? I tested it with the sample codes and some here by the forum / StackOverflow, but none with success. As I said, some even return me to the url of success, as if it had downloaded, but when going to the folder, the file is not there. And in no other folder.

Thank you for your attention!

Can you show your sample code?

Yeah!

I tried using and also without using encodeURI, using the this.file.dataDirectory because it was the only one that came close to working with me. But, as I mentioned, after the “success”, the file was not in the folder.

  downloadDoc(doc: Document) {
    let uri = encodeURI(doc.url);
    const fileTransfer: TransferObject = this.transfer.create();
    fileTransfer.download(uri, this.file.dataDirectory + doc.name).then((entry) => {

    })
    .catch((e) =>{

    });
  }

Thank you!

this.file.dataDirectory + doc.name is this folder already present in your android phone? You will have to create the folder first before inserting a file into it after download.

Yes, from what I’ve noticed, the dataDirectory saves the files in the application’s own folder (in this case it would be io.ionic.starter). Then it exists, but the file does not appear there.

Well, I see no extension for the file, however this isn’t the main reason. Check to see if below works for you. You should probably finding a folder called my_downloads inside which you should see your downloaded file.

// create an instance variable say 'doc'

downloadDoc(doc: Document) {
	this.doc = doc;

    this.file.createDir(this.file.externalRootDirectory, 'my_downloads', false).then(response => {
		console.log('Directory created',response);
		const fileTransfer: TransferObject = this.transfer.create();
	    fileTransfer.download(this.doc.url,this.file.externalRootDirectory + '/my_downloads/' + this.doc.name + '.docx').then((entry) => {
	    	console.log('file download response',entry);
	    })
	    .catch((err) =>{
	    	console.log('error in file download',err);
	    });

	}).catch(err => {
		console.log('Could not create directory "my_downloads" ',err);
	}); 
 }
2 Likes

Test the above code on a real android device not on an emulator(if you were doing so).

Thanks for the code.
I tested and even got to create the directory ‘my_downloads’ but did not save the file, it returns error code 1. Apparently this code refers to file not found, but the URL is correct and working for download outside the ionic. :frowning:

Can you see the folder my_downloads getting created in your android device? Also, does the URL respond to GET http request or something else? Could try it without the encode()?

Can you console.log(this.file.externalRootDirectory + '/my_downloads/' + this.doc.name + '.docx') and see whether it prints an actual legitimate path?

It worked without encode, but only downloaded the first file. From the second no further down and also no error displays. Would it have something to do with the folder already existing from the 2nd download?

  • this.file.createDir ()

Are you doing downloads in a loop? In that case, your loop code needs to be inside the createDir method as you said.

No, I have a list of documents that can be downloaded, the user selects in the list what he wants to download, 1 by 1. Each touch on a document from the list calls the function. Is there a way to check if the directory exists before calling this.file.createDir ()?

Yes, there is a way to check if directory exists using this.file.checkDir. https://ionicframework.com/docs/v3/native/file/

1 Like

Thank you for your attention and help!
It’s working now.

1 Like

Glad to see it’s working now :slight_smile:

1 Like

This helped me a lot. I will post here my code with a function that check if device is using cordova, check if a dir already exists, check if file already exist and then save the file. If device is not using cordova, it will save the file using other method (for browsers). I made some changes as my function already receive the data formatted for my desired format, GeoJSON. Another thing that I changed was the version of File Transfer plugin, now using the updated method/version. This don’t get the file from any server, the data “downloaded” is already on device, I hope this helps someone:

fileTransfer: FileTransferObject = this.transfer.create();
download(file, name) {
	if (this.platform.is('cordova')) {
		this.file.checkDir(this.file.externalRootDirectory, 'downloads')
		.then(
			// Directory exists, check for file with the same name
			_ => this.file.checkFile(this.file.externalRootDirectory, 'downloads/' + name + '.geojson')
			.then(_ => {alert("A file with the same name already exists!")})
			// File does not exist yet, we can save normally
			.catch(err =>
				this.fileTransfer.download(file, this.file.externalRootDirectory + '/downloads/' + name + '.geojson').then((entry) => {
			    	alert('File saved in:  ' + entry.nativeURL);
			    })
			    .catch((err) =>{
			    	alert('Error saving file: ' + err.message);
			    })
			))
		.catch(
			// Directory does not exists, create a new one
			err => this.file.createDir(this.file.externalRootDirectory, 'downloads', false)
			.then(response => {
				alert('New folder created:  ' + response.fullPath);
			    this.fileTransfer.download(file, this.file.externalRootDirectory + '/downloads/' + name + '.geojson').then((entry) => {
			    	alert('File saved in : ' + entry.nativeURL);
			    })
			    .catch((err) =>{
			    	alert('Error saving file:  ' + err.message);
			    });
		
			}).catch(err => {
				alert('It was not possible to create the dir "downloads". Err: ' + err.message);
			})			
		);			 

	} else {
		// If downloaded by Web Browser
		let link = document.createElement("a");
		link.download = name + '.geojson';
		link.href = file;
		document.body.appendChild(link);
		link.click();
		document.body.removeChild(link);
		link = null;
	}
}

construction:

private platform: Platform,
private fileopen: FileOpener,
private file: File,
private ft: FileTransfer,
private document: DocumentViewer,

Open pdf file from url

ViewPDFFromUrl(URL: string, filename: string) {
    filename = filename + new Date().toISOString();
    const transfer: FileTransferObject = this.ft.create();
    transfer.download(URL, this.file.dataDirectory + `${filename}.pdf`).then((entry) => {
      const entryUrl = entry.toURL();
      if (this.platform.is('ios')) {
        //// iOS Version
        this.document.viewDocument(entryUrl, 'application/pdf');
      } else {
        this.fileopen.open(entryUrl, 'application/pdf');
      }
    }, (error) => {
     console.log('Failed!', error);
    });

  }