I have been working with react native at work for 3 years, but I haven't touched the file system.
Recently I built an app called PreCloud: Encrypt before upload, with which you can encrypt texts and files, then you can upload the encrypted texts and files to wherever you want, making any cloud provider an encrypted storage. It's free and open source. Give it a try :)
In this post I will share about managing files with react native.
Libraries used
- react-native-document-picker: Pick files from phone;
- react-native-fs: Manage files in the internal storage of your app, more on this later;
- react-native-share: Share files to other apps;
- react-native-file-viewer: View file in your app;
Two kinds of storage
1. Intertal storage
Every app has its own storage, that other apps don't have access to. For example this is the Cache
folder of my app in Simulator:
/Users/penghui/Library/Developer/CoreSimulator/Devices/5BAEC586-2BA0-42A0-B615-926F1A4D59A0/data/Containers/Data/Application/EBB8401E-3B16-4A3E-98A1-D2DDC3900A90/Library/Caches
And this is the Documents
folder:
/Users/penghui/Library/Developer/CoreSimulator/Devices/5BAEC586-2BA0-42A0-B615-926F1A4D59A0/data/Containers/Data/Application/EBB8401E-3B16-4A3E-98A1-D2DDC3900A90/Documents
There are other folders, but I am only instersted in these 2 for now. You can check the full list in the react-native-fs doc, with more explanation.
I think these are the places where Spotify saves your downloaded music and where Youtube saves your downloaded videos.
react-native-fs is the perfect tool to handle files in internal storage, you can check their doc to find the functions you need.
But like mentioned before, files in the internal storage can't be viewed by your phones Files
app or Photos
app, and you also can't just read files from external storage.
2. External storage
This is the normal storage you see on your phone, it's what you see in the Files
app, both for iOS and Android.
Moving files around
1. From external to internal
react-native-fs is (almost) only for processing internal files. So before it can do something with the file, you need to move it from external storage.
For this we need react-native-document-picker.
We need the pick function, which will open the file picker. We can specify the copyTo param, it supports 2 values: cachesDirectory
and documentDirectory
, what it does is, after users pick a file / multiple files in the file picker, the picked file/files will be copied to the Caches
or Documents
folder of your app's internal storage. Ta-da.
Note: react-native-document-picker can pick all external files on Android (your images, files etc.), but on iOS, it can only pick files in the Files
app, it can't pick images in the Photos
app. You need to firstly "share" an image with the "Save to Files" option, then the image will be moved to Files
, then you can pick it with react-native-document-picker.
If you need to pick images, there are some other libraries, I haven't tried them, but should be straightforward.
2. From internal to external
The file is moved to the internal storage, and you did some fancy processing (For me, I encrypt the file, see some code here), then you want to move the processed file to external storage.
Android
On Android, it's easy, react-native-fs can do the job (remember the "almost" in "react-native-fs is almost only for processing internal files"?) It has a DownloadDirectoryPath, which is only available on Android.
You can use the copyFile function:
await RNFS.copyFile(internalFilePath, `RNFS.DownloadDirectoryPath/${fileName}`);
Then the file will be copied to the Download
folder of the external storage. Done.
You can see some real code here.
iOS
But on iOS, I haven't found an easy way to move a file like that.
I ended up using react-native-share. It will open a share files bottom toolbox, then you can choose the "Save to Files" options to download it to the Files
app.
react-native-share also works on Android of course.
And I mis-used the saveToFiles option :) The flag is only available for iOS. If it's false, and for example you are sharing an image, the opened share toolbox will have other options, like add the image to an album; But when saveToFiles
is true, the toolbox will only show the "Save to Files" option.
So in my app, I have 2 icons under a file, one download icon, for which I set the saveToFiles
flag to true, and one share icon, for which I set the saveToFiles
flag to false.
There is actually another way I found in this answer, which is you set the UISupportsDocumentBrowser
flag in the Info.plist
to true, and you use react-native-fs to save files to the Documents
folder of the internal storage, then the files will be accessible by the Files
app, that's it!
I tried it, it works, but I don't like it, I feel I have less control.
If you know a better way to download files on iOS, please let me know!
Bonus: view internal files in your app
You can use the react-native-file-viewer lib to open internal files, like an image, a PDF file etc. It's very easy to use, have a try.
You can check all my app's code in github;
And if you are interested, try my PreCloud app, to protect your privacy.
Play store: https://play.google.com/store/apps/details?id=com.precloud
App store: https://apps.apple.com/us/app/precloud/id1638793841
Like I said in the beginning, it's free, open source, and has no tracking and no server.
Top comments (0)