-
Notifications
You must be signed in to change notification settings - Fork 887
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
Getting code 1 file exists on file download #367
Comments
I figured out what is going on. If your app downloads the file and then the user manually deletes the file you cannot save the file with the same name again; this is related to some Android caching of some sort. I found this reference here: itinance/react-native-fs#1078 Apparently this started in Android 11+. The proper solutions offered haven't worked for me. But the hack solution does work. If the user manually deleted the file then use the error to "EEXIST" to determine that, then redownload the file again and save it with a slightly different name...add a random character to the end of the name and it will save. |
Whats crazy about this issue is after manually deleting the file with the phones File Manager, my app reads the directory and doesn't see the file. But when writing the file, with the same previous file name, it can't do it because Android says the file is still there. So why is one saying its not there and the other is? |
It sounds like you're experiencing scoped storage rules, which is effective since API 29. I wrote a blip in a PR for the file plugin but the same would apply here. Basically scoped storage applies to all external storage partitions ( With scoped storage, applications do not require permission to read or write files, however it can only read and write files that the application itself has written to. So for example, if another app (Say the chrome browser) downloads a file and stores it at: Listing directories will not show files that your app doesn't have access to. However attempting to write to a filename that already exists will be blocked. There is limited capability of reading files owned by other apps with The file transfer plugin uses the file plugin behind the scenes, which naturally uses the file apis. So how do work with non-media files? Well the native way is to use a non-file API, and use something called a MediaStore. Apache doesn't have a plugin that interfaces with this MediaStore outside of context specific plugins (like the camera plugin which deals with images/video). But there are third-party plugins available that interfaces with the media store with a generic API: https://www.npmjs.com/search?q=ecosystem%3Acordova%20storage%20access%20framework If placing these files in external storage is a requirement, then you'll probably need to use the file transfer plugin to download into your internal cache directory ( Lastly if you support API 29, then using MediaStore APIs is a requirement because Android lacks a filesystem API into scoped storage, which was only introduced in API 30. So accessing any external storage mechanism on API 29 is blocked. If you think any of this sounds bizarre, then you're not alone. You can read learn more about scoped storage in the android docs |
@breautek - As always Norman, you give very thorough explanations and I REALLY appreciate your responses and the time you put into your responses. Android needs to hire you to rewrite their docs because they suck. Based on what you wrote above about reading scoped files I have an additional question. If using this So long as users can download files from my app and open them other apps without issue I am going to continue to use this plugin. It keeps it simple and clean. All I have to do now add code to download the file again, changing the name slightly, if the FileTransfer gets the error with |
This part I'm not 100% sure, but I don't think it will work out of the box. The part that makes it more difficult is the fact that your file are document files, not a media file. (Media as in an image, video or audio). Normally if you had a image file owned by App A. App B could read it without explicit permission from App A if App B has However because you're working with document files, that convenience escape hatch is not available. In order to share document files with other apps, App A needs to implement something called a I could be completely wrong here.... but I believe the typical flow in that kind of use case is that:
Cordova doesn't implement any content providers which is why I don't think it will just work. And I think implementing one will be difficult since the details of a content provider will be largely app-specific. I don't have a complete understanding on the content provider concepts in Android, it's not something I have actually dabbled with. But it is the mechanism for sharing content between apps, from what I can understand. |
@breautek - well....good news. Changing the name allows for redownload of file. And after downloading, navigating to folder with phones general file manager allowed me to open the file with another app. However, the other app did require permissions to access the file; it opens dialog "Go To Settings", which then opens to "All Files Access" forcing the user to allow access for the app they choose to view the file with. Tried it on several different app types and it was the same for all of them. The equally good news is that the other app asks for the permissions, so I don't have to code in my app giving permissions. I don't want the user viewing files in my app anyway...too many issues rendering different file formats in my app - just easier to let native apps do it.
|
@breautek - btw...all of this was on Android. I haven't tested iOS yet. The other issue now is how a user, from within my app, can click a button that then opens the file in another app using some kind of app picker. Trying |
@breautek - final update on this one. On Android, I got everything working on compiledSDK/targetSDK 33.
An update, this worked with only the following permissions set in my
Now...just need to validate all this on iOS. |
Plugin version 2.0.0-7
On Android, downloading files - everything was working and then I changed a bunch of variable and function calls to clean up the code and now its not working. Obviously I changed something but at the moment can't figure out what. A print out of the error code gives me this:
Its the correct source that I can download with the same direct url in a browser. The target is the correct location and file name...and this is the same place it was writing to prior to code changes and breaking. The error implies the file already exists but checking in the folder it does not exist, the path
MyApp/BYG/
does existWhat does this error mean:
Code 1, open failed: EEXIST (File exists)
??From reading other issues,
Code 1
just seems to be a general error code and not specific to the actual problem. I also saw code 1 with apermission denied
messages, so Code 1 just seems to mean a general failureThe text was updated successfully, but these errors were encountered: