My app downloads images from an external resource to the data directory using FileTrasnfer. Now, in one of the pages of my app I'm supposed to display those images.
The paths I used for the images is the exact path they were downloaded to, then I don't understand why the images are not displayed, seems like there is no access to the file
How can I access files in the file.datadirectory?
my code
getfileimage() {
const fileTransfer: FileTransferObject = this.transfer.create();
let options ={
headers:{
'token': this.token,
'sid': this.sid,
'user': this.user,
'type': "image",
'file': this.FileName
}
}
fileTransfer.download(this.apiUrl, this.file.dataDirectory + 'photo.jpg', true, options)
.then(result => {
console.log("getfileimage 2 :- " + JSON.stringify((result)));
console.log("Response data ->>>>>>> :- " + JSON.stringify(result.nativeURL));
// this.imageDis = normalizeURL(JSON.stringify(result.nativeURL));
this.imageDis = JSON.stringify(result.nativeURL);
//console.log("getfileimage :- " +this.imageDis);
}, (err) => {
console.log("Error is: " + JSON.stringify(err));
});
output :-----
getfileimage :- "file:///var/mobile/Containers/Data/Application/E806FDE7-1AF2-4DA2-BC07-E5FEC2E422ED/Library/NoCloud/photo.jpg"
2018-02-26 17:28:11.911819+0530 MyApp[607:174952] THREAD WARNING: ['File'] took '10.540039' ms. Plugin should use a background thread.
2018-02-26 17:28:11.936391+0530 MyApp[607:174952] WARNING: sanitizing unsafe URL value "file:///var/mobile/Containers/Data/Application/E806FDE7-1AF2-4DA2-BC07-E5FEC2E422ED/Library/NoCloud/photo.jpg" (see http://g.co/ng/security#xss)
2018-02-26 17:28:11.970340+0530 MyApp[607:174952] localFile :- cdvfile://localhost/library-nosync/photo.jpg
Related
After searching, testing, coding for over 25h now I hope someone can help me with my problem.
I'm using Cordova (v11) with the File-Plugin and I want to store a file (blob) in the "On my iPhone" directory (on android everything is working fine).
I can save it in the app directory where I can also show it in the inappbrowser but I find no way to store it anywhere else - I want to store it in the "on my iPhone" folder..
Here is the code
saveBlobToSystem(filename, blob) {
filename = 'test.pdf'
let showAlert = true
let folderpath = null
if (this.$q.platform.is.android) folderpath = "file:///storage/emulated/0/download/"; // android --> cordova.file.externalRootDirectory + 'download/'
if (this.$q.platform.is.ios) folderpath = cordova.file.dataDirectory + '' // ios
// folderpath = "cdvfile://localhost/persistent/" + filename;
// folderpath = "cdvfile://localhost/temp/"
const onError = function(msg) {
console.log("Error saving File to System: " + JSON.stringify(msg));
if (showAlert) alert("Error saving File to System: " + JSON.stringify(msg));
};
window.resolveLocalFileSystemURL(folderpath, function(fileSystem) {
console.log("Access to the directory granted succesfully");
if (showAlert) alert("Access to the directory granted succesfully" + folderpath);
fileSystem.getFile(filename, {
create: true,
exclusive: false
}, function(file) {
console.log("File created succesfully.");
if (showAlert) alert("File created succesfully." + JSON.stringify(file));
file.createWriter(function(fileWriter) {
console.log("Writing content to file");
if (showAlert) alert("Writing content to file" + JSON.stringify(fileWriter));
alert('filename' + file.nativeURL)
fileWriter.write(blob);
alert('Datei was downloaded')
console.log("Successfully write file to system");
window.cordova.InAppBrowser.open(file, '_blank', 'location=yes');
}, onError);
}, onError);
}, onError);}
If tried all the tricks with the plist and UIFileSharingEnabled but this doesn't help either.
The strange thing is, that all alert/debug messages looking fine but the one where the data should be written. Because there it says that file is written to a CDV-Path.
wrong file location??
The next debug message "filename" again shows the correct path
correct file location
So I hope anyone has solved that problem already.
I am using react-native-firebase to work with our Firebase account for authentication, firestore and storage. Attempting to upload a photo to Storage is failing with an unknown error. Here is the code attempted:
_pickImage = async () => {
await this.getCameraRollPermission()
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
aspect: [4, 3],
});
console.log(result);
if (!result.cancelled) {
// this.setState({ photoURL: result.uri });
this._handlePhotoChoice(result)
}
};
_handlePhotoChoice = async pickerResult => {
let userId = this.state.userId
firebase
.storage()
.ref('photos/profile_' + userId + '.jpg')
.putFile(pickerResult.uri)
.then(uploadedFile => {
console.log("Firebase profile photo uploaded successfully")
})
.catch(error => {
console.log("Firebase profile upload failed: " + error)
})
}
Testing in iOS Simulator and using the debugger to detect the errors I'm just getting back this error:
"Error: An unknown error has occurred.
at createErrorFromErrorData (blob:http://localhost:19001/e9d43477-4e42-4f7a-b494-16485def4c28:2371:17)
at blob:http://localhost:19001/e9d43477-4e42-4f7a-b494-16485def4c28:2323:27
at MessageQueue.__invokeCallback (blob:http://localhost:19001/e9d43477-4e42-4f7a-b494-16485def4c28:2765:18)
at blob:http://localhost:19001/e9d43477-4e42-4f7a-b494-16485def4c28:2510:18
at MessageQueue.__guardSafe (blob:http://localhost:19001/e9d43477-4e42-4f7a-b494-16485def4c28:2678:11)
at MessageQueue.invokeCallbackAndReturnFlushedQueue (blob:http://localhost:19001/e9d43477-4e42-4f7a-b494-16485def4c28:2509:14)
at http://localhost:19001/debugger-ui/debuggerWorker.js:70:58"
UPDATE:
A file is uploaded to the storage bucket, but the file is not the JPEG photo, but instead is JSON content about the file:
{"contentType":"image\/jpeg","name":"photos\/profile_XPIO2lHjlYbdLPchACZHBsmY9Jr1.jpg"}
So somehow a JSON file is ending up in the bucket instead of the actual photo and then the error is thrown.
It looks like this issue is tracked a couple times, but not resolved:
https://github.com/invertase/react-native-firebase/issues/1177
https://github.com/invertase/react-native-firebase/issues/302
Finally found my issue. The URI of the image from the ImagePicker had a '%' character in it from the local app cache. This percent was being URI encoded to '%25' which resulted in the file not being found by the putFile code. Adding a decodeURI call around the uri fixed the issue.
let fileUri = decodeURI(pickerResult.uri)
In case you are using react-native-document-picker, check out this:
https://github.com/rnmods/react-native-document-picker/issues/235
i want to download a file into my ionic-2-app. i use ionic native Transfer plugin with the following script:
let headers = new Headers();
headers.append('TOKEN-NAME', storedtoken);
let url = storedendpoint.apiendpoint + 'path/to/api/force/download/file';
File.resolveLocalFilesystemUrl(cordova.file.applicationStorageDirectory).then((dirEntry) => {
console.log('resolveLocalFilesystemUrl: ', dirEntry);
this.transfer.download(encodeURI(url), dirEntry.nativeURL + filename, true, {headers: headers})
.then((entry) => {
console.log('Transfer: ', entry);
}, (error) => {
console.log('Transfer Error: ', error);
})
});
But i get the following error:
body: "Could not create target file"
code: 1
exception: null
http_status: 200
source: "http://domain/apiendpoint/api/path/to/api/force/download/file"
target: "file:////var/mobile/Containers/Data/Application/XXXXX-YYYYY-WWWW-1234-DSFR45RFDT65T/filename.doc"
The Download works perfectly if i try it in Browser.
ok, found the problem:
cordova.file.applicationStorageDirectory
is read only. it works with
cordova.file.cacheDirectory
I'm trying to open an already present .pdf file on iOS [I can see the files in iBooks].
I use Ionic and the file-opener2 Cordova plugin - I use the latest versions of Cordova and the plugin.
This is the code that works perfectly on Android:
$scope.openPDF = function() {
alert("OK");
$cordovaFileOpener2.open(
'/storage/emulated/0/Download/pdf/name.pdf', // Any system location, you CAN'T use your appliaction assets folder
'application/pdf'
).then(function() {
console.log('Success');
}, function(err) {
console.log('An error occurred: ' + JSON.stringify(err));
});
};
Yes, I want to be a local file without having to download it, this is a show off app that won't have internet connection where will be running for just one day. So the files have to be local.
I have no idea how to open the file paths like in Android. Running on iOS 9.3.3., iPad Pro. Also, the device is not jail-broken.
Edit:
Well, now I'm trying to move the files from the app's folder to another one, so I can open it from there. Again, all of the code works on Android.
function openPDF(uri) {
var filePath = cordova.file.applicationDirectory + 'www/pdf/fichas/name.pdf';
alert(filePath);
window.resolveLocalFileSystemURL(filePath, function(entry) {
var fileTransfer = new FileTransfer();
var targetFile = cordova.file.externalDataDirectory + entry.name;
fileTransfer.download(
entry.toURL(),
targetFile,
function(entry) {
console.log("download complete: " + entry.toURL());
console.log("targetFile: " + targetFile);
cordova.plugins.fileOpener2.open(
targetFile,
'application/pdf',
{
error : function(error){ alert('open error ' + JSON.stringify(error)) },
success : function(){ }
}
);
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
}
);
}, function(error){ alert('error resolveLocalFileSystemURI ' + JSON.stringify(error)) });
};
alert(filePath); * returns: file:///var/containers/Bundle/Application/xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx/NAME.app/www/pdf/name.pdf
I don't know where it fails though. I won't open anything.
edit2:
I get a FileTransfer error indeed. "
Could not create path to save dowloaded file.
I am building PhoneGap based application for iOS platform.
I want to download few image files to a specific directory.
I want to store downloaded images in folder www/my_img/
So that in my app I can further use this image as:
<img src="my_img/downloaded.jpg" width="100px" height="100px">
I am using PhoneGap plugin for downloading images:
var url = 'http://myServer.com/img.jpg';
var filePath = 'www/my_img/';
var fileTransfer = new FileTransfer();
var uri = encodeURI(url);
fileTransfer.download(
uri,
filePath,
function(entry) {
console.log("download complete: " + entry.fullPath);
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
},
false,
{
headers: {
}
}
);
But problem is image is not getting saved in specified folder.
How can I save downloaded image in "www/my_img/" folder?
The problem is in the value for filePath. This needs to be a device-absolute-file-path or a filesystem URL.
Have a look at the comptibility notes part of the docs:
There are some predefined folders which you can use. I think the most appropriate for your case (it's r/w, without the need to set any permissions and is persistent) is:
cordova.file.dataDirectory
You could store your downloaded image there and, when done, set the image src.
Translating this to your case:
HTML
<img id="downloadedimage" width="100px" height="100px">
JS
var url = 'http://myServer.com/img.jpg';
var filePath = cordova.file.dataDirectory + '/img.png';
var fileTransfer = new FileTransfer();
var uri = encodeURI(url);
fileTransfer.download(
uri,
filePath,
function(entry) {
console.log("download complete: " + entry.fullPath);
document.getElementById("downloadedimage").src = entry.toURL();
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
},
false,
{
headers: {
}
}
);
I think you should before get access to the filesystem. When ok, you can download the image in the folder you create in the dir you got access. If you need, I can give you a snippet.
EDIT:
1) access to the filesystem:
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFSCategory, fail);
}
2) if filesystem's got, get main dir:
function gotFSCategory(fileSystem) {
window.fileSystem = fileSystem;
fileSystem.root.getDirectory(window.appRootDirName, {
create : true,
exclusive : false
}, dirReadyCategory, fail);
}
3) when main dir is ready, save it and go on:
function dirReadyCategory(entry) {
window.appRootDir = entry;
console.log('application dir is ready with window.appRootDir: '+JSON.stringify(window.appRootDir));
// Start my code:
start_my_code();
}
As for the filepath var, I use this one (one for each file):
var filePath = window.appRootDir.toURL() + fileName;