Lepozepo / S3

A simple helper for easily uploading files to Amazon S3 from Meteor. This package will also make Knox available server-side.
MIT License
274 stars 74 forks source link

Error uploading to S3 on Android #129

Closed joaopiopedreira closed 7 years ago

joaopiopedreira commented 7 years ago

Hi @Lepozepo,

First of all, thank you for your hard work on this package. It was a life saver for me.

I've followed the docs and got this working on iOS (10). Everything works as expected.

When I tested on Android (5+) yesterday, though, I've got an error while uploading a photo to S3.

The error fired in the error callback of your S3.upload method as per below:

window.resolveLocalFileSystemURL(fileURI, function (fileEntry) {

        fileEntry.file(function (file) {
            var reader = new FileReader();

            reader.onloadend = function () {
                log.debug('file',this.result);
                var blob = S3.b64toBlob(this.result, mimeType); // 'image/jpg');
                log.debug(blob);

                if (blob) {
                    S3.upload({
                        file: blob,
                        path: bucketSubFolder
                    }, function (e, r) {
                        if (e) {
                            log.error('S3.upload error',e);
                            callback(e,null);
                        }
                        log.debug('S3.upload result',r);
                        callback(null,r);
                    });
                }
            };

            reader.readAsDataURL(file);
        });
    });
};

with a value of "true" (meaning error = true).

After digging around, I'm almost certain that the error was fired somewhere in here:

                xhr.addEventListener "load", ->
                    if xhr.status < 400
                        S3.collection.update id,
                            $set:
                                status:"complete"
                                percent_uploaded: 100
                                url:result.url
                                secure_url:result.secure_url
                                relative_url:result.relative_url

                        callback and callback null,S3.collection.findOne id
                    else
                        callback and callback true,null

                xhr.addEventListener "error", ->
                    callback and callback true,null

(this is when you invoke your meteor method "_s3_sign")

As I said, my code works perfectly well on iOS, but not on Android.

Are there any specifics about Android that I should be aware of?

Thanks 👍

joaopiopedreira commented 7 years ago

The xhr.status returned from within the meteor method "_s3_sign" is 0 (zero), with xhr.statusText blank. A lot of different stuff could be happening here... most likely, the xhr call didn't even started. Any ideas? Thanks

joaopiopedreira commented 7 years ago

Lost many hours to get to the bottom of this... it turns out that, when on Android, the POST request needs a "Content-Length" header with the file size. I've tried to add this to the xhr request but it didn't work.

What did work was to write an alternative upload method using the cordova-file-transfer plugin (if Meteor.isCordova) instead of the standar xhr. Here's my fork if anyone is insterested.

@Lepozepo, if you want I can make a pull request, but this is quite long-winded...