Start a new topic

Upload base64 image to GCS

I have a base64 encoded jpeg string that i would like to send to google cloud storage inside the BL.

I am able using the REST API to upload the content but when i try to view the uploaded file the content is not readable. I have tried to decode the string using modules.utils.base64.decode when putting it to GCS.... Do you have any idea of how to do this?

Hi @gilesvangruisen‌



Yes, using Base64 is a bad idea and only really a passable workaround for very small images. I don't know off the top of my head the answer to your question, but I'm going to get the right person onto it. Hang tight.



Pete
Hi @gilesvangruisen‌



Have you tried using [FileReader.readAsBinaryString](https://developer.mozilla.org/en-US/docs/Web/API/FileReader.readAsBinaryString) or [FileReader.readAsArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/API/FileReader.readAsArrayBuffer) to get the file blob? You could then use this with a PUT with the file. This might suffice unless you are uploading very large images?



Thanks
Yes i tried that also, but the binary returned from cordova doesnt seem correct.

The generated file is corrupted when i try to display/open it.



When using the readAsArrayBuffer, the content gets encoded as a json {size:xxxxx}
Binary encoded file:
Binary read code:





var getFileFromURL = function (url) {

var deferred = $q.defer();

window.resolveLocalFileSystemURL(url, function (entry) {

entry.file(function (file) {



var reader = new FileReader();

reader.onloadend = function (evt) {

deferred.resolve({file:file, binary:evt.target.result});

};

reader.readAsBinaryString(file);





});

});

return deferred.promise;

};



getFileFromURL(vm.imageUrl).then(function (result) {

$kinvey.File.upload(result.binary, {

_filename : 'testangular upload',

mimeType : 'image/jpeg',

size : result.file.size,

}, { 'public' : true }).;

});
ArrayBuffer read file
ArrayBuffer read code:



var getFileFromURL = function (url) {

var deferred = $q.defer();

window.resolveLocalFileSystemURL(url, function (entry) {

entry.file(function (file) {



var reader = new FileReader();

reader.onloadend = function (evt) {

deferred.resolve({file:file, binary:evt.target.result});

};

reader.readAsArrayBuffer(file);





});

});

return deferred.promise;

};



getFileFromURL(vm.imageUrl).then(function (result) {

$kinvey.File.upload(result.binary, {

_filename : 'testangular upload',

mimeType : 'image/jpeg',

size : result.file.size,

}, { 'public' : true }).;

});
Hi @gilesvangruisen‌,



I've spoken to some engineers about your multi-part file upload question. The answer to that is that it's currently not possible to do this with the Kinvey File API. The URL we return is encoded with the request type so you can only make a PUT request to upload your file.



Originally you were trying to achieve this in a onPreSave hook but it sounds now like you've moved your code over to the client side and are attempting to perform the upload from there. In that case I'd suggest that if you are having problems with these file reading methods in Phonegap that instead you use the original base64 encoded string and convert it to a blob using the original suggestion [here](http://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript). It is worth noting that this is broken (I think) in android 4 - but you might be able to come up with a suitable workaround using [this library here](http://www.nihilogic.dk/labs/canvas2image/).
i did move to client side for now but if you have a better solution on the BL, i am happy to try....



I did implement that for now, but looks more like a hack than a proper solution.

I m sure i am not the only client trying to send a photo to Kinvey using phone gap.... might be worse looking for a proper solution.



I ve been testing the decoding on the client side, and for example it doesn't work on iOS 6 (dont know why yet...)

I think that the BL workaround, although an interesting idea, is not a good way to go about the sync issue, as you are going to end up uploading a base64 image string from a mobile device, to Kinvey, which is going to be very inefficient. I think the best way to approach this problem would be just to queue the uploads manually and wait for connectivity. Or perhaps try it, and if it fails, then ask the user to retry the operation.



Are you still using the angular library instead of the phonegap library?
Yes. but i dont think switching to the phonegap one would solve the issue, since the problem comes from what the cordova camera plugin is returning.



What i still dont understand is that according to cordova, the file object you can get calling fileentry.file() is supposed to be the real File object:

https://cordova.apache.org/docs/en/3.0.0/cordova_file_file.md.html#File

According to the documentation there the Phonegap File object only contains attributes, and needs to be used with a FileReader instance to get the contents.
Login or Signup to post a comment