Ionic file transfer error - angularjs

I am using the cordova file transfer and file plugins to go to a server and get some data and image. I am then saving this data to the device's storage, the data format is a .json file and some images. I am able to save all the data to the device.
My problem happens when I try to use that data. When I try to load the local data, I get
Failed to load resource: net::ERR_FILE_NOT_FOUND file:///android_asset/www/Android/data/com.mydomain.myApp/files/data.json
From the console log messages I can see that 'file:///android_asset/www/' is being added to the path when it is being called, is this correct?
I am using the angularjs $resource service.
var localData = $resource(filePath);
If anyone can help I would really appreciate it.

Are you sure that you are storing the files in the right folder?
Reading the Cordova File Plugin documentation you get this:
Where to Store Files
As of v1.2.0, URLs to important file-system
directories are provided. Each URL is in the form
file:///path/to/spot/, and can be converted to a DirectoryEntry using
window.resolveLocalFileSystemURL().
cordova.file.applicationDirectory - Read-only directory where the
application is installed. (iOS, Android, BlackBerry 10)
cordova.file.applicationStorageDirectory - Root directory of the
application's sandbox; on iOS this location is read-only (but specific
subdirectories [like /Documents] are read-write). All data contained
within is private to the app. ( iOS, Android, BlackBerry 10)
cordova.file.dataDirectory - Persistent and private data storage
within the application's sandbox using internal memory (on Android, if
you need to use external memory, use .externalDataDirectory). On iOS,
this directory is not synced with iCloud (use .syncedDataDirectory).
(iOS, Android, BlackBerry 10)
cordova.file.cacheDirectory - Directory for cached data files or any
files that your app can re-create easily. The OS may delete these
files when the device runs low on storage, nevertheless, apps should
not rely on the OS to delete files in here. (iOS, Android, BlackBerry
10)
cordova.file.externalApplicationStorageDirectory - Application space
on external storage. (Android)
cordova.file.externalDataDirectory - Where to put app-specific data
files on external storage. (Android)
cordova.file.externalCacheDirectory - Application cache on external
storage. (Android)
cordova.file.externalRootDirectory - External storage (SD card) root.
(Android, BlackBerry 10)
cordova.file.tempDirectory - Temp directory that the OS can clear at
will. Do not rely on the OS to clear this directory; your app should
always remove files as applicable. (iOS)
cordova.file.syncedDataDirectory - Holds app-specific files that
should be synced (e.g. to iCloud). (iOS)
cordova.file.documentsDirectory - Files private to the app, but that
are meaningful to other application (e.g. Office files). (iOS)
cordova.file.sharedDirectory - Files globally available to all
applications (BlackBerry 10)
Based on this list my advice is for you to usually store files in cordova.file.dataDirectory doing this:
var targetPath = cordova.file.dataDirectory + filename + extension
var fileTransfer = new FileTransfer();
var uri = encodeURI("http://some.server.com/download.php");
fileTransfer.download(
uri,
targetPath,
function(entry) {
console.log("download complete: " + 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: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
It's both compatible with iOS and Android.
For example you can open your downloaded image using the targetPath variable:
//On your controller assign it to the scope
$scope.targetPath = targetPath;
//then on your view just use it as the src for your img
<img ng-src="targetPath">

Ok, so I was doing this all wrong. Because the data is local I shouldn't be making a $resource request. I have instead used readAsText(path, file) from the ngCordova documentation.
Essentially when I am saving the data to a .json file it is being treated as a text file, I can then use the method about in conjunction with JSON.parse(data); this can then be set to my scope and used in the same way as the remote data.
P.S. I have tried with both 'cordova.file.dataDirectory' and 'cordova.file.externalDataDirectory' and both worked in my tests. And the info offered by 'Fabio Antunes' in this post is worth a read.

Related

.NET / React App not serving /.well-known/filename

I'm trying to setup Apple Pay via Stripe, which requests access to a file to verify domain ownership. The problem I'm having is that this file has no extension, so either React, Azure or my .NET application does not like it!
I've tried various solutions to date within the web.config but to no avail.
The file in question is: /.well-known/apple-developer-merchantid-domain-association
My project is a .NET project running a React SPA. I've added the file mentioned above to the /public folder, too.
I can access .txt files in the same folder, so the path/folder is accessible - It seems to be a problem with the lack of extension.
I've managed to resolve this with the following, and ensuring the ./well-known and subfiles are in my project root.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, #".well-known")),
RequestPath = new PathString("/.well-known"),
DefaultContentType = "application/json",
ServeUnknownFileTypes = true
});

How to save a file on shared space in Cordova with Android?

I am using Apache Cordova with cordova-plugin-file to develop some android app. Since Android API 29 (Android 10), apps no longer have access to shared space directly due to privacy issues.
I was storing some pdf file on file:///storage/emulated/0/Download/ from where the user could then open the pdf file.
window.resolveLocalFileSystemURL('file:///storage/emulated/0/Download/', function (dir) {
dir.getFile(filename, { create: true }, function (file) {
file.createWriter(function (fileWriter) {
console.log('Writing content to file')
fileWriter.onwriteend = function () {
console.log('Successful file write...')
}
fileWriter.onerror = onerror
fileWriter.write(DataBlob)
}, onerror)
}, onerror)
}, onerror)
But that stopped working on Android 10.
How can I store now a file to be accessible by the user?
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory + "/Download" used to work
This should work as is when targeting API 28 (now forbidden by Google Play)
This should work when targeting API 29 with the dev version of the plugin (which has the android:requestLegacyExternalStorage="true"), alternatively you can use the edit-config to add this flag.
This won't work when targeting API 30, as API 30 ignores the android:requestLegacyExternalStorage attribute.
It's important to read the Android Notes before you target API 30. You may need to migrate your files to another folder to maintain access to them when targeting API 30 using the new APIs. Source.
Solution for up to Android 10 (API 29)
Use the dev version of the plugin
cordova plugin rm cordova-plugin-file
cordova plugin add https://github.com/apache/cordova-plugin-file.git
I tested it and it allows me to use cordova.file.externalRootDirectory + "/Download" in Android 10 (API 29)

upload pdf file from local system to aws-s3

In my serverless app, I need to generate pdf dynamically and then upload that generated pdf into aws-s3 bucket. But in serverless, we can only sent json request, so I sent my html string to serverless, it generate pdf and then save that generated pdf into local machine. I think, that part I can do, But my problem is, I need to upload that newly generated pdf into aws-s3. My code is given below:
Angular Code:
$scope.generate_pdf = function() {
var html = angular.element('html').html();
var service = API.getService(); // sent html string as json for generating pdf
service.downloadPdf({}, { html : html },
function(res) {
console.log("res : ", res); // res.url: /tmp/dynamica-generate.pdf
// pdf is saved into '/tmp' folder
// now I want to upload pdf from '/tmp' folder to aws-s3
}, function(err) {
console.log("err : ", err);
});
};
How can I solve this problem, Thanks in Advance.
If you want to upload file from your local machine to S3 bucket. Install AWS Cli on your local machine. after that is done add a cron job for this command
aws s3 sync /tmp/* s3://mybucket
You should be able to use the aws Javascript S3 sdk to integrate JS code into your angularJS code.
You can follow from this blog post and github code
Its also mentioning about setting up the credentials using a public IAM account. Depending how you serve the files to your clients, you might check also using Pre-Signed URL’s.

how can I enable the user download the whole application from the client side?

So, I have a web app hosted in heroku which is automatically updated when I update my github repository. I want to enable the user to download the all the app files with their folders, images etc as a zip from the client side so he can run it offline locally. I also want to add a file with user's comments to that zip before I force it to be downloaded on his browser.
I found a way to do it by redirecting him to github (but this will actually not redirect him there, it will just force a zip from github to be downloaded) :
window.location.replace("https://github.com/foo/FOO/archive/master.zip");
But this solution doesn't work for me because I want to add to that zip an other file which will be created at the moment of the user download request.
Does anyone have a solution to this?
Is there a way to do that by making requests to herokku to receive the files and using the jszip to pack them?
I found the solution using github's service, JSZipUtils and jszip. Here's the code for whom it might of help :
var content = null;
JSZipUtils.getBinaryContent("https://github.com/foo/FOO/archive/master.zip", function(err, data) {
if(err) {
throw err; // or handle err
}
var zip = new JSZip(data);
// to remove a not needed file
zip.remove("CWAPP-master/abc.js");
// to add a custom file
zip.file('CWAPP-master/myClientSideFile.js',file);
content = zip.generate({type:"blob"});
saveAs(content, 'myZip'); // force download
});

AngularJS 1.2 Not allowed to load local resource

I know it would be great if the file wouldn't link to local resource, but using phonegap/steroids framework, FILE_URI returns "file:///Users/" path which I can use for uploading to S3 or else, but Angular won't show it in the template.
Is there a possible solution? I tried adding config to my app
.config(function ($compileProvider){
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
})
but it seems that doesn't have impact on the error.
I can base64 encode my images (then works), but I would like to avoid this if possible.
thanks
See the Camera example in the Steroids Kitchensink app, where the Cordova File API is used to move the picture from the tmp folder to the Steroids app's User Files folder. Since Steroids's localhost looks for assets both in the App folder and User Files folder, you can use an absolute path, e.g. src="/my_image.png". See also the App Structure on Device guide for more information on the App and User Files folder.

Resources