Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to load assets image with Version > 10 #1316

Closed
3 tasks done
EinfachHans opened this issue Aug 9, 2021 · 11 comments
Closed
3 tasks done

Failed to load assets image with Version > 10 #1316

EinfachHans opened this issue Aug 9, 2021 · 11 comments

Comments

@EinfachHans
Copy link
Contributor

Bug Report

Problem

I'm currently migrating my project to cordova-android@10. In my Project i'm using Googlemaps and Markers that icons are in my assets Folder. These are not working anymore and displays the default Google Map Marker.

Information

I see the following Error when i run my App via debugger:

E/AsyncLoadImage: can not connect to https://localhost/assets/imgs/map/mapPinGreen/mapPinGreen.png
    java.net.ConnectException: Failed to connect to localhost/127.0.0.1:443
        at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:147)
        at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106)
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)
        at plugin.google.maps.AsyncLoadImage.doInBackground(AsyncLoadImage.java:299)
        at plugin.google.maps.AsyncLoadImage.doInBackground(AsyncLoadImage.java:27)
        at android.os.AsyncTask$3.call(AsyncTask.java:394)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:923)

Maybe the migration from the whitelist Plugin is not correctly working?

Environment, Platform, Device

Google Pixel 4, Android 10

Version information

Ionic:

   Ionic CLI                     : 6.16.3 (/usr/local/lib/node_modules/@ionic/cli)
   Ionic Framework               : @ionic/angular 5.6.12
   @angular-devkit/build-angular : 12.1.4
   @angular-devkit/schematics    : 12.1.4
   @angular/cli                  : 12.1.4
   @ionic/angular-toolkit        : 4.0.0

Cordova:

   Cordova CLI       : 10.0.0
   Cordova Platforms : android 10.0.1
   Cordova Plugins   : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 5.0.0, (and 50 other plugins)

Utility:

   cordova-res (update available: 0.15.3) : 0.15.1
   native-run (update available: 1.4.0)   : 1.0.0

System:

   Android SDK Tools : 25.2.3 (/Users/hanskrywalsky/Library/Android/sdk)
   ios-deploy        : 1.10.0
   ios-sim           : 8.0.2
   NodeJS            : v14.15.4 (/usr/local/bin/node)
   npm               : 7.17.0
   OS                : macOS Big Sur
   Xcode             : Xcode 12.5.1 Build version 12E507

Checklist

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above
@EinfachHans EinfachHans changed the title [10.0.1]: Failed to load assets image Failed to load assets image with Version > 10 Aug 25, 2021
@breautek
Copy link
Contributor

breautek commented Sep 3, 2021

ooph...

I think this might be because native code is external from the webview, and localhost server doesn't actually exist to anything outside the webview (I think...). Not 100% sure, but a theory.

There are two workarounds you can try...

Remapping https:// paths to local file:// paths

Anything you tell google maps to load can probably be remapped from https://localhost/assets/imgs/map/mapPinGreen/mapPinGreen.png to file:///android_assets/imgs/map/mapPinGreen/mapPinGreen.png

Basically replace https://localhost/assets with file:///android_assets/

Not really sure if this will work, but it's worth a try.

Opting out of WebAssetLoader

You can tell cordova to opt out of using the WebAssetLoader system by enabling the AndroidInsecureFileModeEnabled preference, which will make it use file based paths just like cordova-android@9. I'm pretty sure this will work.

@EinfachHans
Copy link
Contributor Author

Currently i'm giving the Google Maps Plugin a Url like ./assets/imgs/...someFile.png and i'm unsure about what is done then. To make iOS work and as i don't want to adjust all icons to android vs iOS the first option is not an option for me.

The second option, setting the AndroidInsecureFileModeEnabled Preference, seems to work, but does this will have any side effects?

Is this something that the Google Maps Plugin has to fix/migrate?

@erisu
Copy link
Member

erisu commented Sep 6, 2021

Cordova Android 10.x by default will use scheme+hostname. And Cordova-iOS 6.x I believe will always use scheme+hostname.

The scheme can not match exactly because of limitations between each platform but the following example should work.

But needs to be tested as I do not use this plugin.

Setup:

Let’s say you have an image uploaded at this directory path.

<project-root>/www/assets/image.png

WebView Paths:

With Cordova iOS 6.x default settings, the path would be: app://localhost/assets/image.png.

With Cordova Android 10.x and default settings, the path would be: https://localhost/assets/image.png

Recommendation:

Would be recommended to pass in the absolute path, /assets/image.png.

You might also be able to use //localhost/assets/image.png. With this pattern is should automatically detect the scheme but the hostname setting must be identical.

Catches:

Now, not everyone can use the https protocol because they might load external third party resources or api requests to the http scheme and these can’t mix. At least https, a secure protocol can not call and insecure protocol. If you are faced with this issue, in case of Android, you can change the scheme to http.

Now for the AndroidInsecureFileModeEnabled setting… This preference is for people who want to revert to the file protocol which 9.x and earlier used. It’s not recommended to serve from the file protocol as there can be security concerns. But depending on how the app is written and if the third party scripts is coming from a trusted source, and you know everything that is executed, then maybe it’s less of a problem.

First try the above recommendation:
Remove the . and make your path absolute, with default android and iOS settings for scheme+hostname, and see how that turns out.

@EinfachHans
Copy link
Contributor Author

Passing the absoulte Path like /assets/image.png or like //localhost/assets/image.png both doesn't work:

W/System.err: java.io.FileNotFoundException: /assets/imgs/map/mapPinGreen/mapPinGreen.png: open failed: ENOENT (No such file or directory)
W/System.err: java.io.FileNotFoundException: /localhost/assets/imgs/map/mapPinGreen/mapPinGreen.png: open failed: ENOENT (No such file or directory)

@erisu
Copy link
Member

erisu commented Sep 6, 2021

Sorry, I was mistaken about where the error was. I thought it was from the WebView side but, I see it was the native side of the plugin.

It will need to be the path that @breautek suggested.

file:///android_assets/imgs/map/mapPinGreen/mapPinGreen.png

But, this path will not work for iOS.

Try his other suggestion, to confirm that it will work: AndroidInsecureFileModeEnabled

Maybe the correct solution would involve a change/feature request to the plugin developers. Since you are passing the path to the plugin, and the plugin is trying to fetch the file with native code, maybe the plugin should accept various string values and determine the correct path.

E.g. Various String Values:

  • The new scheme+hostname value, which the native side will need to map to the native file path.
  • The exact native file path.
  • A partial path that of either:
    • native file path
    • scheme+hostname

Maybe, there could be something implemented on our platform's code to help translate the file paths to native paths, etc, but then it would include app developers updating the app code and wrap file paths. For some reason, I would feel that this isn't the best solution compared with the plugin change.

@breautek any thoughts?

@EinfachHans
Copy link
Contributor Author

Yeah the AndroidInsecureFileModeEnabled Preference seems to work so far. I think at the end of the day the plugin needs to update this 🤔

@breautek
Copy link
Contributor

breautek commented Sep 6, 2021

Thanks for confirming, i think my suspicions are accurate.

When using the web asset loader, the only thing that understands the https://localhost url is the webview itself. Anything external won't be able to use this url.

I think at the end of the day the plugin needs to update this

I think so too, but I'm not quite sure what the solution would be. Native could probably parse the url and transform it to a regular file:// url. I think the cordova plugin class could also provide this url transform implementation. I think this is what @erisu was hinting but wasn't quite recommending. Obviously the problem is plugins will need to be updated, but I'm not sure if there is a way around that.

Do you have a similar issue with iOS? I have one app that uses gmaps & custom markers, but it hasn't been updated. If necessarily I can find time to get the latest platforms installed to confirm

@breautek breautek closed this as completed Sep 6, 2021
@breautek breautek reopened this Sep 6, 2021
@EinfachHans
Copy link
Contributor Author

iOS works fine with latest cordova-ios version

@ebhsgit
Copy link
Contributor

ebhsgit commented Oct 23, 2021

@EinfachHans
I've made a fix for myself.
I've created PR mapsplugin/cordova-plugin-googlemaps#2887 if you want to use it.

@nanaykubo
Copy link

nanaykubo commented Dec 31, 2023

@EinfachHans I've made a fix for myself. I've created PR mapsplugin/cordova-plugin-googlemaps#2887 if you want to use it.

This helps

and include to install this also

https://www.npmjs.com/package/cordova-plugin-file/v/8.0.1

@jcesarmobile
Copy link
Member

This is something the plugin needs to handle, not a cordova-android bug

@jcesarmobile jcesarmobile closed this as not planned Won't fix, can't repro, duplicate, stale Jan 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants