DEV Community

Peng
Peng

Posted on

Internal and external storage in react native

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


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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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}`);
Enter fullscreen mode Exit fullscreen mode

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)