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.42k forks source link

console.warn: Native: tried accessing the FileTransfer plugin but it's not installed. #2110

Closed arup-b closed 3 years ago

arup-b commented 6 years ago

We are developing an app which uses Native File Transfer plugin. But due to a weird issue we can not create the Test Flight / Release Build for iOS.

Issue: Even after successful installation of the 'File Transfer' plugin we see the following error while running the app with

ionic cordova run ios -lc

console.warn: Native: tried accessing the FileTransfer plugin but it's not installed.

Current behavior:

As we tap a button that invokes the fileTransfer.download(..) method - the app halts to perform without throwing any Error.

Console Output

[19:21:39]  console.log: Hello MediaIos Provider 
[19:21:39]  console.log: Ionic Native: deviceready event fired after 2822 ms 
[19:21:39]  console.log: fileTransfer: 
[19:21:39]  console.log: 
            {"FileTransferErrorCode":{"FILE_NOT_FOUND_ERR":1,"INVALID_URL_ERR":2,"CONNECTION_ERR":3,"ABORT_ERR":4,"NOT_MODIFIED_ERR":5}}
[19:21:39]  console.log: platform ready now 
[19:21:39]  console.log: AuthToken Checking Complete 
[19:21:39]  console.log: ViewDidLoad SelectSurvey 
[19:21:39]  console.log: ionViewDidEnter SelectSurvey 
[19:21:51]  console.log: fileTransfer: 
[19:21:51]  console.log: provider ios: {} 
[19:21:51]  console.log: documentsDirectory: 
            file:///var/mobile/Containers/Data/Application/E92C5A5F-4ABB-4ECF-8AED-C45B19468155/Documents/ 
[19:21:51]  console.log: download started on uri: http://xxxxxxxx.com/softwareapp/media/xxxxxxxx.zip

I would like to draw attention at the following lines -

1:

[19:21:39]  console.log: 
            {"FileTransferErrorCode":{"FILE_NOT_FOUND_ERR":1,"INVALID_URL_ERR":2,"CONNECTION_ERR":3,"ABORT_ERR":4,"NOT_MODIFIED_ERR":5}}

The above is the result of the console.log() we placed inside the platform.ready() function as follows:

console.log('fileTransfer: ');   
console.log(JSON.stringify(this.fileTransfer));

The console.log(JSON.stringify(this.fileTransfer)); at least prints an object with some properties.

2: Now, we placed the same two lines of console.log() in the provider where the download operation code resides. The output printed on the console is surprisingly different as follows:

[19:21:51]  console.log: fileTransfer: 
[19:21:51]  console.log: provider ios: {} 

The second line of console.log() just prints an object literal ( EMPTY OBJECT !!! ??? )

And at this point - the app stops without throwing further Error and the download never completes.

As a side note, I would mention that the Android Version of the finished app already been released on Google Play and working fine with all its features.

Plugin List As we run ionic cordova plugin list we get the following output on the console window:

cordova-plugin-compat 1.2.0 "Compat"
cordova-plugin-device 1.1.4 "Device"
cordova-plugin-file 4.3.3 "File"
cordova-plugin-file-transfer 1.6.3 "File Transfer"
cordova-plugin-inappbrowser 1.7.1 "InAppBrowser"
cordova-plugin-ionic-webview 1.1.16 "cordova-plugin-ionic-webview"
cordova-plugin-network-information 1.3.3 "Network Information"
cordova-plugin-screen-orientation 2.0.1 "Screen Orientation"
cordova-plugin-splashscreen 4.0.3 "Splashscreen"
cordova-plugin-statusbar 2.2.3 "StatusBar"
com.hutchind.cordova.plugins.streamingmedia 0.1.4 "StreamingMedia"
cordova-plugin-whitelist 1.3.1 "Whitelist"
cordova-plugin-zip 3.1.0 "cordova-plugin-zip"
cordova-sqlite-storage 2.1.1 "Cordova sqlite storage plugin"
cordova.plugins.diagnostic 3.7.1 "Diagnostic"
ionic-plugin-keyboard 2.2.1 "Keyboard"

Related code:

The actual download function is as follows:

download_media_files() {
    //
    console.log('fileTransfer: ');   
    console.log('provider ios: ' + JSON.stringify(this.fileTransfer));
    //
    this.fileTransfer.onProgress((e) => {
      this.process_str = 'Downloading ... '
      this.process_progress = (e.lengthComputable) ? Math.round(e.loaded / e.total * 100) : -1;
      console.log("progress: " + this.process_progress);
    })

    let uri = encodeURI(this.zip_path);

    //
    console.log('documentsDirectory: ' + this.file.documentsDirectory);
    console.log('download started on uri: ' + uri);

    this.fileTransfer.download(uri, this.file.documentsDirectory + '/media/xxxx.zip').then((entry) => {
      console.log('download complete: ' + entry.toURL());

      // to unzip the downloaded zip file
      this.unzip_files();
    }, (error) => {
      console.log('error block');
      console.log(error);
    })
  }

Other information:

Ionic info: output is as follows:

ionic info

cli packages: (/Users/<user-name>/.nvm/versions/node/v8.3.0/lib/node_modules)

    @ionic/cli-utils  : 1.18.0
    ionic (Ionic CLI) : 3.18.0

global packages:

    cordova (Cordova CLI) : 7.1.0 

local packages:

    @ionic/app-scripts : 3.0.1
    Cordova Platforms  : ios 4.5.3
    Ionic Framework    : ionic-angular 3.8.0

System:

    ios-deploy : 1.9.2 
    Node       : v8.3.0
    npm        : 5.5.1 
    OS         : macOS Sierra
    Xcode      : Xcode 9.1 Build version 9B55 

Environment Variables:

    ANDROID_HOME : not set

Misc:

    backend : pro

Any help ??

arup-b commented 6 years ago

Dear Support Providers,

We have finally sorted out this issue. The File Transfer plugin can now be accessed at the Provider where the actual download happens.

What is missing is a CLEAR & DETAILED documentation of ionic native wrapper detailing how to instantiate and use the Native Plugins. I won't call it a bug - but blurry documentation is just a trap for developers.

I am refraining from posting the solution here - because - a recent Tweet attracted my attention where it was mentioned if developers would wish to get more help in lieu of a subscription. The irony is - we had to invest 3 valuable weeks to make the app run successfully on iOS as the documentation is not adequate.

Thanks.

kensodemann commented 6 years ago

@DevlprArup - I am glad to hear you got that sorted out.

For the documentation bit, my suggestion is to use the "Improve this doc" link and submit a PR with the improvements or clarifications that you would like to see in the document. A large component of any open source project is community support, and if you could contribute to that via needed clarifications to the documentation, that would be really great. If you don't feel comfortable doing that, that's cool too.

arup-b commented 6 years ago

@kensodemann Yes .. I do agree with you. And I trust that should be a developer's TRUE SPIRIT.

I actually sent a direct Tweet to a Boss of the Ionic - seeking help on the issue -- I never received a single word as a response - instead saw a Tweet from the boss proposing subscription based help.

It hurts and I AM HURT.

mlynch commented 6 years ago

@DevlprArup we are doing our best, but I hope you understand that it's just not possible for a team of ~30 to provide one-on-one support on a free basis to millions of Ionic developers. Also, I cannot respond to every tweet nor have I ever set that expectation.

We can help best through community channels, and in a way that allows others to see the solution when they encounter it again in the future.

That's how we can best balance improving the software (which is an incredible challenge), and also help those using it.

arup-b commented 6 years ago

@mlynch Thanks for responding on my issue.

When I sent a direct tweet to you - I was in extreme confusion with the code and the issue. I failed to meet the deadline - and was utterly clueless. I felt like clutching the last straw when the sea was closing on me. And the proposal of subscription based help just thawed me.

Let's get back to the code : My issue was that the FileTransfer object could be accessed from inside the platform ready function but not inside a provider - this too on iOS [ Android version is working correctly ]

Here is what I did:

As I need an instance of the FileTransfer inside the provider - i created a variable - and an updater method -

private fileTransfer: any;

public setFileTransferRef( param ){
      this.fileTransfer = param;
  }

And as I could access the FileTransfer inside the platform.ready() - I instantiated the FileTransferObject right there and updated the provider as follows -

initializeApp() {
    this.platform.ready().then(() => {
        console.log('fileTransfer: ');   
        console.log(JSON.stringify(this.fileTransfer));
        //
        let fileTransfer: FileTransferObject = this.fileTransfer.create();
        //
        this.mediaIOSProv.setFileTransferRef(fileTransfer);
        .....
        ....

What I presume is - [ I may be wrong.. please rectify if needed ]

1: It would be best to create a Provider to store references of each Native Plugin instantiated within the platform ready - and use the references as and when needed

2: There might be some information missing, specially regarding iOS, about the Ionic-Native Wrapper

3: I also placed with the cordova.js inclusion after build/vendor.js in the index.html - ( I came across some posts where developers reported that doing so solved their missing plugin issue ) - Though there is no such official documentation.

<body>

  <!-- Ionic's root component and where the app will load -->
  <ion-app></ion-app>

  <!-- The polyfills js is generated during the build process -->
  <script src="build/polyfills.js"></script>

  <!-- The vendor js is generated during the build process
       It contains all of the dependencies in node_modules -->
  <script src="build/vendor.js"></script>

  <!-- cordova.js required for cordova apps -->
  <script src="cordova.js"></script>

  <!-- The main bundle js is generated during the build process -->
  <script src="build/main.js"></script>

</body>

Since the app successfully ran on iOS - I did not dare to change the placement of cordova.js

Any suggestion is welcome.

jcsubmit7 commented 6 years ago

I consider that the "documentation" should not be referred to as "documentation" but more a taster of what might possibly function if you spend a good few days beating on it and searching on stackoverflow etc. On a number of occasions I have had replies from staff intimating how proud they were of the doco. When I supplied examples of where the doco was wrong or missing, answer came there none. I have to grit my teeth and allocate a day or so each time I try to use a new native feature - none has ever worked as documented. I appreciate the work put into creating a potentially valuable product, but the lack of attention to the doco must put off miriad developers. I wonder myself why I am still hanging in there.

devotoare commented 6 years ago

This exact issue is happening to me as well when I try to use FileTransfer to upload an image to my server. It only effects builds on iOS, but works using Ionic Dev App on an iOS device, which makes it even more confusing.