Flutter: cannot download file from object url in webview - android

I need to download, from a mobile app developed in flutter 1.22.2, a file generated by a php script. The file is available in blob format.
The javascript code in the web page is:
response.blob()
.then(blob => URL.createObjectURL(blob))
.then(url => {
let a = document.createElement('a');
a.href = url;
a.download = 'modulo-' + JobRiskIden + '.pdf';
a.target = '_blank';
document.body.appendChild(a);
a.click()
a.remove();
})
Where "response" variable is the response from a fetch to a php page that generates the file.
I followed the instructions from this stackoverflow question:
Flutter WebView blob pdf download
The download works fine on iOS but an issue is present on Android (test done with compileSdkVersion 29): when I tap on the download link the debugger prints this message:
{message: Not allowed to load local resource: blob:https://apps.badgebox.com/62edb40f-4407-4d3b-8427-587ea133b778, messageLevel: 3}
Can someone help me to solve this issue?

Related

Download Word .docx as Blob file from Angular on mobile devices

I am trying to download .docx file from REST API (.NET Core FileContentResult) in Angular application. Everything is working fine on PC, but there is problem with downloading .docx files in VMware Workspace ONE Web browser (didn't try standard browsers like Chrome or Safari, it looks like there is just Android WebView). It is company application and this browser is the only one allowed.
The problem is only with .docx files. Files like PDF, .doc and .xlsx (created by ClosedXML) are working fine.
REST API call (also tried with 'arraybuffer' instead of 'blob' and created Blob object in client, but problem persists)
this.httpClient.get(requestUrl, {
responseType: 'blob',
observe: 'response'
});
Then I save response body with FileSaver.
generateDocument(file: string | Blob, name: string): void {
FileSaver.saveAs(file, name);
}
I also tried approach that creates link and click on it (it does not work).
Solution with using window.open(blobUrl) is not working.
EDIT:
I got information that it is not working at all in iOS with same browser. Users get error message "Link is invalid."
Can someone help me with this issue? Thanks.
If you can retrieve obtain an ArrayBuffer, this could be used to initiate the download with those bytes:
Test here: https://batman.dev/static/70085191/
async function downloadUrl(url) {
downloadBuffer(
await (await fetch(url)).arrayBuffer()
)
}
function downloadBuffer(arrayBuffer) {
const a = document.createElement('a')
a.href = URL.createObjectURL(new Blob(
[ arrayBuffer ],
{ type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }
))
a.download = 'my-file.docx'
a.click()
}

How convert base64 to pdf React-Native

I created an app using react-native and have some base64 data from
api. I want convert base64 data to pdf format. if you have any idea
please help me. thanks.
You can use react-native-pdf package (https://www.npmjs.com/package/react-native-pdf). If you want to show the pdf in your app , this package would be quite helpful as it supports loading PDFs from base64 string for both ios and android . You can specify the pdf's source from your base64 data as shown in their example :
{uri:"data:application/pdf;base64,JVBERi0xLjcKJc..."}
I'm assuming, converting to PDF as in saving the base64 format data as PDF in some file.
the following code can help you do the same,
let fPath = Platform.select({
ios: fs.dirs.DocumentDir,
android: fs.dirs.DownloadDir,
});
fPath = `${fPath}/pdfFileName.pdf`;
if (Platform.OS === PlatformTypes.IOS) {
await fs.createFile(fPath, base64Data, "base64");
} else {
await fs.writeFile(fPath, base64Data, "base64");
}
// RNFetchBlob can be used to open the file

Ionic, upload image or string to firebase not working on Android, but working in browser and iOS

since about 3 days I am trying to upload an image to the firebase storage without success.
I tried several approaches I found here in stackoverflow.
It is even not possible to upload a simple string for Android.
Running the app in the browser is working fine for images and strings.
Emulator and phone returns the same error:
Firebase Storage: An unknown error occurred, please check the error payload for server response.
I don't know where should I check the mentioned "payload"
This is my code for uploading the string:
EDIT: I changed the function which retrieves the error to
alert(error.serverResponse);
this returns following Error message: "Multipart body does not contain
2 or 3 parts"
$scope.upload = function() {
//storage reference
var storage = firebase.storage();
//path reference
var storageRef = storage.ref();
var uploadTask = storageRef.child('testfile.png').putString("any string").then(function(snapshot) {
console.log('upload successful');
alert('ok');
}, function (error) {
// Handle unsuccessful uploads
//alert(error.message);
alert(error.serverResponse);
});
The function added below can help you to add an image on firebase where(file is the image you wish to add ).
$scope.addImage = function(file){
var fileRef = storageRef.child(file.name);
fileRef.put(file).then(function (snapshot) {
console.log(snapshot)
});
};

Show PDF downloaded from API in Ionic / Angular

I need to hit an API endpoint, which returns a pdf file (not a url to a pdf, but the actual data), then somehow display this pdf in my ionic application. Ideally, I'd like to just give it to some other application like the phone's mobile web browser but I'd be open to trying to embed it within my app as well. On iOS, I just use $window.open(url) and mobile safari knows to download and display the pdf that is returned. However, Android tries to download the file then tells me that it can't be opened when I try to open it.
I've also tried embedding it in the app with <embed> but nothing gets embedded. However, a similar method works with images in <img ng-src="url">.
I've also tried messing around with cordova FileOpener2 but am having a lot of trouble getting anything to work in that. If that's the right way to do this, I'd be open to re-visiting that method.
The closest I've gotten is definitely just sending it to the devices mobile browser as that works perfectly on iOS.
I solved it using filetransfer and fileopener2. My code is below. The main issues I ran into was not having <access origin="cdvfile://*" /> in my config.xml file and not having ngCordova installed correctly.
if (ionic.Platform.isIOS())
$window.open(APIUrl, '_blank', 'location=no');
else if (ionic.Platform.isAndroid()) {
var fileExtension = filename.substr(filename.lastIndexOf('.')+1);
//I have a dictionary with this somewhere else
var MIMEType = extToMime[fileExtension];
var uri = encodeURI(APIurl);
var fileURL = "cdvfile://localhost/persistent/file."+fileExtension;
$cordovaFileTransfer.download(uri, fileURL, {}, true)
.then(function(result) {
$cordovaFileOpener2.open(
fileURL,
MIMEType
).then(function() {
console.log("SUCCESS");
}, function(e) {
console.log("ERROR");
console.log(JSON.stringify(e));
});
}, function(e) {
console.log("Error: " + JSON.stringify(e));
});
}

upload image file from jquery to node.js

I am trying to upload a file from andriod application, using Jquery to node.js using express..
My client side code is:
function uploadData(win) {
var padI = imagedata.length-1
while( '=' == imagedata[padI] ) {
padI--
}
var padding = imagedata.length - padI - 1
var user = load('user')
$.ajax({
url:'http://'+server+'/lifestream/api/user/'+user.username+'/upload',
type:'POST',
contentType: false,
processdata:false,
data:imagedata,
success:win,
error:function(err){
showalert('Upload','Could not upload picture.')
},
})
}
I have used post form without any content type because if i use multipart/form-data it says error about boundary ..
my server side code using node.js is:
function upload(req,res) {
var picid=uuid()
console.log('Got here..' + __dirname)
//console.log('Image file is here ' + req.files.file.path)
// console.log('local name: ' + req.files.file.name)
var serverPath = __dirname+'/images/' + picid+'.jpg'
fs.rename(
req.files.file.path,
serverPath,
function(error) {
if (error) {
console.log('Error '+error)
res.contentType('text/plain')
res.send(JSON.stringify({error: 'Something went wrong saving to server'}))
return;
}
// delete the /tmp/xxxxxxxxx file created during download
fs.unlink(req.files.file.path, function() { })
res.send(picid)
}
)
}
when the file comes to server, it gives an error of res.files.file is undefined ..
I have searched alot of forums, they say that res.files.file is only access when contenttype is multipart/form-data but then the boundary problem occurs
Any help on that is highly appreciated
Boundary is a special sequence of characters that separates your binary data.
You should submit MIME type as multipart/form-data, as well as set your imagedata to FormData() type (from your snippet it's not clear if it is FormData type).
Here are similar issues and solutions:
How to set a boundary on a multipart/form-data request while using jquery ajax FormData() with multiple files
jQuery AJAX 'multipart/form-data' Not Sending Data?
A great alternative to writing this code is to use filepicker.io This allows you to connect to yoru own s3 bucket. When the file is saved, you get back a callback with the S3 url, you can then simply pass that url to your node api, and save it. I have used this to avoid having to write extra server code for handling file uploads. Extra bonus, if you need to do this with images, and want users to be able to edit the images, you can use Aviary which allows an image to be edited locally, and you then get back another s3 url, that you can then save to your server..

Categories

Resources