danielsogl / awesome-cordova-plugins

Native features for mobile apps built with Cordova/PhoneGap and open web technologies. Complete with TypeScript support.
https://danielsogl.gitbook.io/awesome-cordova-plugins/
Other
2.41k stars 2.43k forks source link

File.readAsArrayBuffer promise never resolves #978

Closed pdrosos closed 7 years ago

pdrosos commented 7 years ago

May be related to #505

I am opening another issue, as #505 is closed and as the code I use is different. Unfortunately this seems to happen on a random basis and I can not isolate it - I just change other non related parts of my code and this bug sometimes just happens on Android or on iOS. It happens long after platform is ready and app is opened. All the code of the app is inside this.platform.ready()

I have methods, which select image from image library or take a new image with the Camera plugin. After that image is cropped with the Crop plugin and finally the cropped image content is read with File.readAsArrayBuffer When the bug appears, it doesn't work both for images, selected from image library and new images, taken with Camera.

This is the code for selecting an image from image library, crop and read image content:

ImageService.ts

public selectImage(): Promise<string> {
    return Camera.getPicture({
        sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
        mediaType: Camera.MediaType.PICTURE,
        correctOrientation: true
    });
}

public cropImage(url: string): Promise<string> {
    return Crop.crop(url);
}

public selectImageAndCrop(): Promise<string> {
    return new Promise((resolve, reject) => {
        this.selectImage()
            .then((imageUrl: string) => {
                this.cropImage(imageUrl)
                    .then((croppedImageUrl: string) => {
                        console.log('Image cropped');
                        resolve(croppedImageUrl);
                    })
                    .catch((error) => {
                        console.log('Crop error: ' + JSON.stringify(error));
                        reject(error);
                    })
                ;
            })
            .catch((error) => {
                console.log('Select image error: ' + JSON.stringify(error));
                reject(error);
            })
        ;
    });
}

public getImageData(url: string): Promise<ArrayBuffer> {
    return new Promise((resolve, reject) => {
        console.log('File url: ' + url);
        File.resolveLocalFilesystemUrl(url)
            .then((entry: Entry) => {
                console.log('Entry: ' + JSON.stringify(entry));
                entry.getParent((directoryEntry: Entry) => {
                    console.log('Directory entry: ' + JSON.stringify(directoryEntry));
                    File.readAsArrayBuffer(directoryEntry.nativeURL, entry.name)
                        .then((imageData: ArrayBuffer) => {
                            console.log('File read');
                            resolve(imageData);
                        })
                        .catch((error) => {
                            console.log('Can not read file: ' + JSON.stringify(error));
                            reject(error);
                        })
                    ;
                }, (error) => {
                    console.log('Can not resolve file directory: ' + JSON.stringify(error));
                    reject(error);
                });
            })
            .catch((error) => {
                console.log('Can not resolve file path: ' + JSON.stringify(error));
                reject(error);
            })
        ;
    });
}

ProfilePage.ts

private handleChooseProfileImageFromLibrary() {
    this.imageService
        .selectImageAndCrop()
        .then((croppedImageUrl: string) => {
            console.log('Image will be uploaded');
            this.updateProfileImage(croppedImageUrl);
        })
        .catch((error) => {
            console.log('Choose profile image error: ' + JSON.stringify(error));
        })
    ;
}

private updateProfileImage(imageUrl: string) {
    this.imageService
        .getImageData(imageUrl)
        .then((imageData) => {
            //upload image
        })
        .catch((error) => {
            console.log('Update profile image error: ' + JSON.stringify(error));
        })
    ;
}

Problem is in ImageService.ts - getImageData method. Only sometimes, after some unrelated changes in my code, File.readAsArrayBuffer promise never resolves. console.log is not executed neither from .then, nor from .catch function and my code stops executing at this place.

Any help or clue why this happens will be appreciated. Thanks!

ihadeed commented 7 years ago

Modify your index.html. Make sure cordova.js is loaded after polyfill.js

pdrosos commented 7 years ago

I have seen https://github.com/driftyco/ionic-native/issues/505#issuecomment-273504996 and did it in a moment I had this issue in Android. Seems fixed indeed! Will close this for now, I hope this is the permanent solution to problem.

joewoodhouse commented 7 years ago

I don't really understand why this (and similar) issues have been closed. Everyone is referencing my "fix" which is actually a hack to re-order things in the index.html file (see https://github.com/ionic-team/ionic2-app-base/issues/126). There still doesn't seem to be a proper solution to this.

rlekkr commented 7 years ago

I have the same issue and the fix don't do it (cordova.js is loaded after polyfill.js). In my package.json: "'ionic-native/file": "^4.3.3", "cordova-plugin-file": "^4.3.2", "ionic-angular": "3.9.2", "ionic": "3.17.0"

My code:

 this.file
    .readAsArrayBuffer(filepath, filename)
    .then((body: any) => {
        let params = {
           Key: `${message._id}/${data.name}`,
           Body: body,
           ACL: "public-read"
        }; 
    })
      ...
odmera commented 7 years ago

Can someone help me please?

I have the same issue and the fix don't do it (cordova.js is loaded after polyfill.js) In my package.json:

"ionic-angular": "3.7.0", "'ionic-native/file": "^4.4.0", "cordova-plugin-file": "^4.3.3",

My code let readAsBinaryString = await this.file.readAsBinaryString(this.file.dataDirectory, this.filename); alert('readAsBinaryString' + JSON.stringify(readAsBinaryString) ); ......

yosigolan commented 6 years ago

i have the same issue, it happens only when compiling in production. i am using the new release of file (5.0.0)

pdescham49 commented 6 years ago

@ihadeed That was the issue.. order of operations issue with the JS flipped cordova / pollyfill zero code changes.. Presto.. :+1:

jineshmehta16 commented 6 years ago

There are lot of people for whom fix doesn't worked even after reordering and I am one of them. For those whose fixed worked after reordering can you please paste here the package.json versions for all plugins so we can compare with it and have accurate version for the work around.This will be of huge help.

Thanks in Advance!

yosigolan commented 6 years ago

Hey @jineshmehta16 here are my plugins: "dependencies": { "@angular/animations": "5.2.11", "@angular/common": "5.2.11", "@angular/compiler": "5.2.11", "@angular/compiler-cli": "5.2.11", "@angular/core": "5.2.11", "@angular/forms": "5.2.11", "@angular/http": "5.2.11", "@angular/platform-browser": "5.2.11", "@angular/platform-browser-dynamic": "5.2.11", "@ionic-native/app-availability": "4.9.0", "@ionic-native/browser-tab": "4.9.0", "@ionic-native/call-number": "4.9.0", "@ionic-native/clipboard": "4.9.0", "@ionic-native/core": "4.9.0", "@ionic-native/device": "4.9.0", "@ionic-native/facebook": "4.9.0", "@ionic-native/file": "4.9.0", "@ionic-native/file-transfer": "4.9.0", "@ionic-native/geolocation": "4.9.0", "@ionic-native/google-maps": "4.8.2", "@ionic-native/google-plus": "4.9.0", "@ionic-native/in-app-browser": "4.9.0", "@ionic-native/keyboard": "4.9.0", "@ionic-native/launch-navigator": "4.9.0", "@ionic-native/media-capture": "4.9.0", "@ionic-native/network": "4.9.0", "@ionic-native/photo-library": "4.9.0", "@ionic-native/pro": "4.9.0", "@ionic-native/screen-orientation": "4.9.0", "@ionic-native/splash-screen": "4.9.0", "@ionic-native/status-bar": "4.9.0", "@ionic/pro": "1.0.20", "@ionic/storage": "2.1.3", "@mapbox/polyline": "1.0.0", "@ngx-translate/core": "9.1.1", "@ngx-translate/http-loader": "2.0.1", "android-versions": "1.3.0", "angular2-moment": "1.9.0", "call-number": "1.0.1", "cordova-android": "6.3.0", "cordova-browser": "5.0.3", "cordova-clipboard": "^1.2.1", "cordova-ios": "4.5.4", "cordova-plugin-actionsheet": "^2.3.3", "cordova-plugin-add-swift-support": "1.7.2", "cordova-plugin-appavailability": "^0.4.2", "cordova-plugin-browsertab": "^0.2.0", "cordova-plugin-compat": "^1.2.0", "cordova-plugin-device": "^2.0.2", "cordova-plugin-dialogs": "^2.0.1", "cordova-plugin-facebook4": "^2.2.0", "cordova-plugin-file": "^6.0.1", "cordova-plugin-file-transfer": "^1.7.1", "cordova-plugin-geolocation": "^4.0.1", "cordova-plugin-globalization": "^1.11.0", "cordova-plugin-googlemaps": "^2.2.5", "cordova-plugin-googleplus": "^5.3.0", "cordova-plugin-inappbrowser": "^3.0.0", "cordova-plugin-ionic": "^4.1.7", "cordova-plugin-ionic-webview": "^1.2.1", "cordova-plugin-media-capture": "^3.0.2", "cordova-plugin-network-information": "^2.0.1", "cordova-plugin-photo-library": "^2.1.1", "cordova-plugin-screen-orientation": "^3.0.1", "cordova-plugin-splashscreen": "^5.0.2", "cordova-plugin-statusbar": "^2.4.2", "cordova-plugin-whitelist": "^1.3.3", "cordova-sqlite-storage": "^2.3.3", "es6-promise-plugin": "^4.2.2", "font-awesome": "4.7.0", "http-status-codes": "1.3.0", "ionic-angular": "3.9.2", "ionic-img-viewer": "2.9.0", "ionic-plugin-keyboard": "^2.2.1", "ionicons": "4.2.4", "minimatch": "3.0.4", "minimist": "^1.2.0", "mx.ferreyra.callnumber": "0.0.2", "rxjs": "5.5.11", "sw-toolbox": "3.6.0", "uk.co.workingedge.phonegap.plugin.launchnavigator": "^4.2.1", "update": "0.7.4", "upgrade": "1.1.0", "weather-icons": "1.3.2", "web-animations-js": "2.3.1", "xml2js": "^0.4.19", "yargs": "12.0.1", "zone.js": "0.8.26" },

DjulLau commented 6 years ago

Having this problem too and investigating at the moment... Maybe this is due to an incompatibility between zone.js and the cordova file plugin : https://github.com/angular/zone.js/issues/868 https://stackoverflow.com/questions/45542462/angular-4-x-cordova-filereader-fails-silently-white-screen-of-death

sta55en commented 5 years ago

Almost 2 years on and still a problem.

kctang commented 5 years ago

I've a production app (ionic 3.2) built about a year ago, all working fine. When I rebuild it last week (no changes), this issue happened. 😭

Moving cordova.js as the last script to load in index.html solves the issue.

AleFons commented 4 years ago

I'm still seeing this problem; it happens at complete random; using zone.js 0.8.26 here. Reordering my plugins has a chance to create loading chunk errors across the app.

elvisgraho commented 4 years ago

Same issue with ionic 5

coolvasanth commented 4 years ago

I'm also facing same issue in my Ionic 4 application. Any fix please ?

Bhavese commented 4 years ago

I have same Issue in ionic 4 Application, any solution ?

coolvasanth commented 4 years ago

I commented on May 6 even after almost 50 days, I haven't received any updates, issue still exists. Looking out for solution.

WilsonFpz commented 4 years ago

I remove ionic-platform-web-client, and it work.FYI.

ghost commented 4 years ago

Same issue with Ionic 5 (and Capacitor). Initially I thought there was an issue with Capacitor File API as well, but I have to revise. When using the the readFile method it seems to be fine. Hopefully this entry helps somebody who's not stuck with pure Cordova.. https://capacitorjs.com/docs/apis/filesystem#method-readFile-0

AleFons commented 4 years ago

Same issue with Ionic 5 (and Capacitor). Initially I thought there was an issue with Capacitor File API as well, but I have to revise. When using the the readFile method it seems to be fine. Hopefully this entry helps somebody who's not stuck with pure Cordova.. https://capacitorjs.com/docs/apis/filesystem#method-readFile-0

@dani-inside Are you sure about that? What options do I need to use to read as an array buffer?

ghost commented 4 years ago

@AleFons : I just checked again what we did – and there is no array buffer being return from the Capacitor File API, so your doubt was right. It returns the data as base64 string. Instead we integrated a method to convert to an array buffer... That's just not how it should be, but working for us for now.

public base64ToArrayBuffer(base64: string): ArrayBuffer {
    let binary_string = window.atob(base64.replace(/\s/g, ""));
    let len = binary_string.length;
    let bytes = new Uint8Array(len);
    for (let i = 0; i < len; i++) {
      bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
  }
TomaszQwerty commented 4 years ago

any news about this issue? It still does not work : |

rohitsethi007 commented 4 years ago

Hi, has anyone got this working in an Ionic 5 app? This is making me nuts!

mayankkataria commented 3 years ago

I have seen #505 (comment) and did it in a moment I had this issue in Android. Seems fixed indeed! Will close this for now, I hope this is the permanent solution to problem.

@pdrosos No its not a permanent solution, kindly reopen that. We are still facing this issue. And in ionic capacitor everything is changed, can't find cordova.js file. How to make this solution work in Ionic 5?

DeMeng33 commented 3 years ago

I have same Issue in ionic 5 Application, any solution ?

Vingtoft commented 3 years ago

This problem has not been fixed!!

CSHaze commented 2 years ago

Still not fixed!

glv1at118 commented 2 years ago

I don't see where the cordova-plugins are "awesome". This is total mess. For me "this.file.readAsArrayBuffer" doesn't show anything. Neither resolved nor rejected, and without any errors showing. Wasted too much time on these incapable packages that causes bugs everywhere.