Cordova fileWriter.write() doesn't work with blobs - javascript

In the official documentation and many other solutions posted online, the following code is supposed to be the way of writing data to a file in Cordova
function writeFile(fileEntry, dataObj) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.write(dataObj);
});
}
writeFile(someFileEntry, blob);
In the documentation, they explicitly shown that a blob can be passed as the "dataObj", but whenever I passed a blob as "dataObj", the resulting file only has 2 bytes of data. After inspecting the file, I found that the contents of the file only contain a single string
{}
hence the 2 bytes.
I've tried passing a string as the "dataObj", and the contents of the resulting file was the exact same string, so string works I guess? But the data I'm wishing to write to a file is a blob that contains video data recorded from a canvas, so either I'll have to
somehow convert the the video blob into a string and write the string into the file
somehow fix the "fileWriter.write" function
But I've gone nowhere with these solutions. I've tried "blob.text()" or using a "fileReader" to get the contents of the blob as a string, but the resulting file is always broken. And fixing the "fileWriter.write" function is way out of my depth. Can someone help me out on this?

I am having the same issue. I think it might have something to do with the following as stated on the cordova-plugin-file docs:
But I find that odd since the examples all use FileWriter.write(blob) but it says that the platforms do not support that function.

Related

PDFMake Base64 generates malformed document

I'm using PDFMake to generate some PDF reports on client side.
When I specify the definition for document and pass it to createPdf(DEFINITION_HERE) I get my PDF and it looks nice and shiny. But I'm saving it in the DB as Base64 encoded string and when I try to reopen it with data URI (ie: data:application/pdf;base64,JVBER...) the document is completely malformed.
My DB call looks like this:
await pdfFile.getDataUrl(async (result: string) => {
await myServiceLayer.generatePdfReport(result, fileName, creator);
});
Anyone else had this issue with PDFMake library? Any ideas on what could be the cause of this?
OK, so after trying different things and debugging left and right, I stumbled upon this:
https://github.com/bpampuch/pdfmake/issues/318
So I removed call to .download() on my PDF file and checked for Base64 again, now it had correct value and file looks as it should.
So in a nutshell, if we call multiple methods on PDFMake, usually something will get messed up.
I had my .download() call just before my .getBase64() as I wanted to first download the file for the user and then also store it in DB as Base64, as .download() happened .getBase64() kept on giving me Base64 output which resulted in malformed PDF file.

Unsure if an existing project is using blob files of some other data format

I am working on an application that was created by a colleague that is no longer with the company. I am trying to open what I believe is a PDF in blob file format, but none of the tutorials is giving me the expected result.
I notice that I have some data preceding what I believe to be the blob file, leading me to wonder if I am understanding what I am working with correctly. The whole blob is too large to post here, but this is how it starts:
data:application/pdf;base64,JVBERi0xLjcNJeLjz9MNCjIxIDAgb2JqDTw8L0xpbmVhcml6ZWQgMS9MIDQyMTExNC9PIDIzL0UgMzc0MzIwL04gMi9UIDQyMDU3NC9IIFsgMjYxNiA0NDhdPj4NZW5kb2JqDSAgICAgICAgICAg
In the posts and tutorials I am reading, like this one for instance, they use code similar to this:
var file = new Blob([response], {type: 'application/pdf'});
Since my blob file includes the "application/pdf" portion as part of the string, I am starting to wonder if I misunderstood and that this is another kind of file instead of a blob. I have also seen other examples of blob files, and they also do not include the "data:application/pdf;base64,".
I am having issues opening the files in a browser if they are too large. I have outlined my problem in this post, but have yet to receive any advice, so I am trying to find a different way to approach this. The results are not as expected, which leads me to wonder if I am looking for the right thing.
Here is what I have tried and what the result is:
var file = new Blob([upload.split(',')[upload.split(',').length - 1]], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
I remove the "data:application/pdf;base64," portion of the string using "[upload.split(',')[upload.split(',').length - 1]]", thinking that this will leave me with only the blob data, but this invariably fails to open, giving me the below result:
So my question is this: Am I working with a blob file or not? If not, what kind of data file is this so I can start looking for more relevant tutorials?
"Blob files" aren't really a thing. You can think of the term "blob" as "just some binary data", or if you're a database vendor, call them "Binary Large OBject"s.
Your data:application/pdf;base64,JVBERi0xLjcNJeLjz9MNCjIxIDAgb2JqDTw8L... string is a data URL; a way to represent arbitrary binary data in an URL string. Since the URI has the base64 marker, you know the data is encoded as Base64 and you can use any Base64 decoder you can find (there are plenty online) to decode the data.
Your (truncated) data begins
%PDF-1.7
%
21 0 obj
<</Linearized 1/L 421114/O 23/E 374320/N 2/T 420574/H [ 2616 448]>>
endobj
so it is representing something like a valid PDF file.

Why does encoding wav file to base64 with python and online webapp give different results?

I am making a simple web app that needs to play a some audio files, using howler.js. howler.js accepts base64 URI as input, so I wanted to try that out. To test it, I took a sample audio file and used an online audio-to-base64 encoder to get the base64 URI. I added the data description ("data:audio/wav;base64,") the front of the base64 string and copy and pasted into the following JS function...:
function playSound() {
var data = "";
var sound = new Howl({
src: [data],
loop: false
});
sound.play();
}
...and it worked perfectly. Since I would be dealing with a fair number of audio files, I figured I'd use a short python script to convert them all to the base64. To test, I converted the same audio to a base64 string with the following python code:
import base64
with open("0.wav", "rb") as f1,open("b64.txt", "w") as f2:
encoded_f1 = base64.b64encode(f1.read())
f2.write("data:audio/wav;base64,")
f2.write(str(encoded_f1))
I noticed the base64 string was different front the one I got from the website earlier. I pasted this into the JS function shown earlier, but when I attempt to play the sound, I get the following error:
Uncaught DOMException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
There seems to be some sort of difference in the way python is encoding to base64. What could the cause for this be?
Came back to this after a while and the problem became apparent. It was just a problem with the block of code I mentioned in OP (the second block) that I used to write the base64 encoding to a file.
base64.b64encode(f1.read()) returns a bit string, which in Python, is symbolized with the following notation (i.e. when you print/write it, you'll see it like this): b'string goes here'. So the issue was just that the b' ' was wrapped around my actual base64 string, and I was using that. All I had to do get rid of the b' ' which I did by converting the bitstring to ASCII like this: str(encoded_f1,'ascii', 'ignore').
Really silly mistake, but hopefully it helps someone out.

AWS S3 getting Not a valid bitmap file

I have been struggling with this for a while and I am going to provide you with as much information as possible (some maybe irrelevant) because I am completely stuck. I am using Ionic and I would like to be able to take a picture with my phone and upload it to an AWS S3 bucket. I used Cordova camera to accomplish this.
As far as I know; these pictures come out in a large base64 string and I have to convert it to a Blob, convert it to a File object then upload that file object into AWS. However, when I do this it always uploads it as something other than an image. Whenever I open it I get an error saying:
"Not a valid bitmap file. its format is not currently supported."
https://s3.amazonaws.com/mng-moment/moment/PA/40.008446_-75.26046_1502414224619.jpg
Here is an example of a WORKING one (This used to work it somehow broke):
https://s3.amazonaws.com/mng-moment/bestMoments/40.008446_-75.26046_1499659199473.jpg
I tried to open each one in a text editor to see what is going on. For the first one (The broken one) I get this:
When I try to open the working one in a text editor I get this:
Now it seems like a conversion problem but I think I am converting it correctly.
Here is the code I am using to upload (You can see the console.logs later on the post):
core.js
awsServices.js
If you look at the comments in the code I labeled some of the console logs. I will display them here for more information:
A - (uploadToAWS):
B - (awsServices.upload):
This is how I convert the dataURI to a Blob (Called in uplpoadToAWS - The first screenshot):
This is what gets passed into the 'dataURI' parameter in the code right above:
If there is any more information please let me know. I've been scratching my head at this for a while. Any help is appreciated. Thanks!
As stated in MDN File API:
A File object is a specific kind of a Blob, and can be used in any context that a Blob can. In particular, FileReader, URL.createObjectURL(), createImageBitmap(), and XMLHttpRequest.send() accept both Blobs and Files.
So, i think your problem reside in your uploadToAws function because you first create a Blob and then use the Blob to create a File, when I think you simply should initialize the File object with the byte array returned by dataURItoBlob since the File object is in fact already a Blob object.

Check typeof text data

I have a string like in this link http://pastie.org/private/n7bu5qlknphtyyv5sqla.
I am trying to decode it using different methods
new Uint8Array(encodedString);
and also tried some octal decoders online but no success. Can anyone help me to understand encoding type and how to decode it.
Edit:
Progress: It is a file loaded from client side. Before I was using readAsBinaryString and now I changed it to reader.readAsArrayBuffer(blob); Now I am getting ArrayBuffer and converted it to new Uint8Array(arrayBuffer). It seems now I have some data zipped data.

Categories

Resources