Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downloading a file (with expo) — Why is this so hard?

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:

enter image description here

I'm very new to react native and javascript, but why does simply downloading a file seem to be so difficult, any help?

like image 522
Tizer1000 Avatar asked Jul 16 '18 00:07

Tizer1000


People also ask

Is Expo worth using?

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.

What is EXPO file system?

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.


2 Answers

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)
    }
}
like image 112
anro Avatar answered Oct 02 '22 12:10

anro


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

like image 40
Furquan Avatar answered Oct 02 '22 14:10

Furquan