I've been trying multiple ways to download a file to local storage in react native, non of which are working. Here's my code in App.js where I am calling FileSystem.downloadAsync.
import React from 'react';
import { AppRegistry, StyleSheet, Text, View, TouchableHighlight, Image, Linking, PixelRatio, ListView } from 'react-native';
import { createStackNavigator } from 'react-navigation'
import MainScreen from './Components/MainScreen'
import FileSystem from 'react-native-filesystem';
export default class App extends React.Component {
  render() {     
    return (
      FileSystem.downloadAsync(
        'http://techslides.com/demos/sample-videos/small.mp4',
        FileSystem.documentDirectory + 'small.mp4'
      )
        .then(({ uri }) => {
          console.log('Finished downloading to ', uri);
        })
        .catch(error => {
          console.error(error);
        }),
      <AppStackNavigator />
    );
  }
}
const AppStackNavigator = createStackNavigator({
  Main:{
    screen: MainScreen
  }
})
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
AppRegistry.registerComponent('Recap', () => App);
I'm getting this error:

I'm very new to react native and javascript, but why does simply downloading a file seem to be so difficult, any help?
Here are some good reasons to use Expo to build your React Native app. If you are given a project that needs rapid development, and you have picked React Native to build the cross-platform app, Expo is the best fit for you. With Expo, you can build and deploy React Native apps for both iOS and Android with ease.
expo-file-system provides access to a file system stored locally on the device. Within Expo Go, each project has a separate file system and has no access to the file system of other Expo projects.
I haven't tested this on ios, but it works perfectly on Android, saving file to Download directory:
import * as MediaLibrary from 'expo-media-library';
import * as FileSystem from 'expo-file-system';
import * as Permissions from 'expo-permissions';
downloadFile(){
    const uri = "http://techslides.com/demos/sample-videos/small.mp4"
    let fileUri = FileSystem.documentDirectory + "small.mp4";
    FileSystem.downloadAsync(uri, fileUri)
    .then(({ uri }) => {
        this.saveFile(uri);
      })
      .catch(error => {
        console.error(error);
      })
}
saveFile = async (fileUri: string) => {
    const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
    if (status === "granted") {
        const asset = await MediaLibrary.createAssetAsync(fileUri)
        await MediaLibrary.createAlbumAsync("Download", asset, false)
    }
}
I was able to download all types of files in expo sdk-38, it was not at all hard, There is just one problem, You will have to create a folder (maybe with your app name if you like), then download all files in that(or their children), Images/video will show up directly, to see other files you will have to download related file-explorer. see reference
downloadFile = async (url) =>{ 
    let path = url.split('/');
    const file_name = path[path.length-1];
     FileSystem.downloadAsync(
      url,
      FileSystem.documentDirectory + file_name
    )
      .then(({ uri }) => {
        console.log('Finished downloading to ', uri);
        MediaLibrary.createAssetAsync(uri).then(asset => {
          console.log('asset', asset);
        MediaLibrary.createAlbumAsync('myfolder', asset)
          .then(() => {
            showMessage({
              message: t('general.success'),
                description: t('download.success'),
              type: 'success'
            });
          })
          .catch(error => {
            showMessage({
              message: t('general.success'),
                description: t('download.failed'),
              type: 'danger'
            });
          });
        });
        
      })
      .catch(error => {
        console.error(error);
      });
  }
Keep in mind Im downloading files (Xls, doc, etc) via HTTP URL, then converting it into local URI, if you already have local URI (maybe from expo-camera / expo-image-picker lib). You should use the above code from line 9 Hope it helps someone
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With