Skip to content

Uncaught typeError: Wrong type for parameter "uri" of resolveLocalFileSystemURI #646

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

Open
rolinger opened this issue Jan 30, 2025 · 4 comments

Comments

@rolinger
Copy link

rolinger commented Jan 30, 2025

On app startup, I am using the following code to check if an app directory exists and if not create it. It has worked fine forever - but on one users device I suddenly got the above error three times, once per each time the user started the app (within minutes of each other). This user is on Android 12, and has had my app on his device for about 3 months and had started it 17 times previously without the error, then on starts 18, 19 and 20 suddenly started generating this error:

Uncaught typeError: Wrong type for parameter "uri" of resolveLocalFileSystemURI

if (ionic.Platform.isAndroid()) {
      window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function (directoryEntry) {
        directoryEntry.getDirectory("downloads", { create: true, exclusive: false}, 
          function(success) {
            errMgmt("ctrl/init",1004.5,"Android 'downloads' folder created") ;   
          },
          function(err) {
            errMgmt("ctrl/init",1004.6,"Android 'downloads' folder failed "+err) ;   
          }
        ) ;
      }) ;
    }

I have the following preferences set in my config.xml file:

    <preference name="AndroidPersistentFileLocation" value="Compatibility" />
    <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,root" />

The user did not remove and reinstall the app at any point. Its from the original install several months ago, so what could cause this error to suddenly kick in?

@breautek
Copy link
Contributor

cordova.file.externalDataDirectory isn't guaranteed to exist and the value can be null if the device doesn't have emulated external storage or external storage attached. It might be a reason for:

Uncaught typeError: Wrong type for parameter "uri" of resolveLocalFileSystemURI

That's just speculation though.

@rolinger
Copy link
Author

Weird...I would imagine that error happened on users first time app install and use....not months later, unless they changed phones and the new phone doesn't have external storage, but as best I can tell the user is still on the same device. What do you recommend I use so its internal to the device...not external? And switching to internal memory, on the app, I believe it wouldn't change the behavior...its still an internal directory to the app that the user can't physically get to, just a different location right?

I wish Android did file systems the way iOS does. On iOS my app shows up as a folder in the users public "downloads" folder, its just symlink to the real folder embedded within my app directory structure. Clean and simple.

@breautek
Copy link
Contributor

IF externalDataDirectory is actually null, then it would be the first time I've ever heard of it being null if I were to be honest. I thought all modern devices emulate external storage if there is no actual physical removable mediums present. So it is still weird.

What do you recommend I use so its internal to the device...not external? And switching to internal memory, on the app, I believe it wouldn't change the behavior...its still an internal directory to the app that the user can't physically get to, just a different location right?

I don't know if I can answer that because it would depend on your own use case but I can give information.

Historically the internal storage is a partition that is fixed on device, and external storage was always removable disk, such as a SD card. It was recommended to use external storage when possible since the internal storage capacity was limited. At some point, devices started to emulate SD cards for devices that lack them, or simply don't have a SD card, probably for app compatibility reasons. Today, in my personal experience, using internal storage is fine unless if you have some use cases that involves sharing files. I exclusively use internal storage in my apps, storing large log files without issue or complaints.

just a different location right?

dataDirectory is the internal storage version of externalDataDirectory and yes it is a different. Internal storage is "more" private than external storage. While externalDataDirectory is still app-specific, users can pull files by removing the sd card and inserting it on a PC or whatever. The internal app-specific data directory is only accessible by your own application.

Changing to use dataDirectory means you'll need a migration strategy for your existing app users.

I believe it wouldn't change the behavior

There are some behaviour changes between internal and external storage since API 29 / Scoped Access Framework introduction. I can't remember on top of my head if SAF restrictions apply to app-specific external directories however, so behaviour differences might not apply to you here.

SAF restrictions do not apply to internal storage.

I wish Android did file systems the way iOS does. On iOS my app shows up as a folder in the users public "downloads" folder, its just symlink to the real folder embedded within my app directory structure. Clean and simple.

The android equivalent folder for this would be externalRootDirectory + "Downloads/ (we don't have a constant for the downloads directory), however the file plugin read/write access to this will be limited due to SAF restrictions. SAF restricts direct access via the native File APIs, so to modify many parts of the external filesystem requires using the MediaStore APIs, which the File plugin does not (and likely won't) implement.

MediaStore APIs is not very "filesystem-like" so it's not very feasible trying to interface with it from a "filesytem" api perspective.

@rolinger
Copy link
Author

rolinger commented Feb 5, 2025

@breautek - as always, thanks for your thorough explanations. Well, turns out this particular user has a Moto G Pure. A quick google search for does moto g pure phone have emulated external storage? returns:

No, the Moto G Pure does not have emulated external storage, but it does support a microSD card for additional storage. You can use the microSD card as portable storage or internal storage.

That phone comes with 32G internal memory....so I am guessing the user doesn't have a microSD or removed it. I think maybe he removed it because my app launched without issue like 18+ times, then the last few times it started breaking. I think I am just going to move everything to dataDirectory. Or I need some code to check for externalDataDirectory, then if doesn't exist, use the dataDirectory - this is probably preferred so all existing users can still get to their existing files and dataDirectory will only ever be used for phones that don't have external, emulated or not.

To do this I think it would be, any comments would be appreciated:

     var appDataDir ;
      window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, 
         function (directoryEntry) {  // SUCCESS external exists, then create 'downloads' here
           appDataDir = cordova.file.externalDataDirectory ;
           directoryEntry.getDirectory("downloads", { create: true, exclusive: false}, 
             function(success) {
             },
             function(err) {
             }
           ) ;
      },
      function (err) {  // FAIL, external does not exist
         window.resolveLocalFileSystemURL(cordova.file.dataDirectory, 
            function(directoryEntry) {  // SUCCESS internal exists, create downloads here
              appDataDir = cordova.file.dataDirectory ;
              directoryEntry.getDirectory("downloads", { create: true, exclusive: false}, 
                function(success) {
                },
                function(err) {
                }
              ) ;
         }) ;
      }) ;

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

2 participants