DEV Community

Johanna
Johanna

Posted on • Updated on

Downloading and Displaying a file in React Native

React Native does not currently offer full support for downloading and showing a file. The approach in this article shows you how to download and display a file using the react-native-fs and react-native-webview libraries respectively.

In this example, the file is of a PDF format, however, the same approach can be used for images or other text file formats.

Prerequisites:

A working React Native App. Not sure how to do this? Checkout the setup instructions on the React Native Website.

Downloading the file

Install react-native-fs:

yarn add react-native-fs
Enter fullscreen mode Exit fullscreen mode

or

npm install react-native-fs
Enter fullscreen mode Exit fullscreen mode

If you're using React Native version 0.60.0 or higher, it a does auto-linking for you. If not, check the extra setup instructions on react-native-fs page.
Install the CocoaPods dependencies (iOS specific):

cd ios && pod install
Enter fullscreen mode Exit fullscreen mode

Using downloadFile function:

In this example, I will be retrieving a PDF file from an API endpoint using the downloadFile function from react-native-fs. This function has two required parameters - fromUrl and toFile , along with several other optional ones. I created an async function downloadPDF which requires a url and fileName. It also contains a basic header with an authorization token and content-type.

React-native-fs' DocumentDirectoryPath provides the Android or iOS where documents are stored. You can change this to your customised path if you wish.

downloadPDF = async (url: string, fileName: string): Promise<any> =>{
//Define path to store file along with the extension
const path = `${DocumentDirectoryPath}/${fileName}.pdf`;
const headers = {
  'Accept': 'application/pdf',
  'Content-Type': 'application/pdf',
  'Authorization': `Bearer [token]`
}
//Define options
const options: DownloadFileOptions = {
  fromUrl: [baseUrl] + url,
  toFile: path,
  headers: headers
}
//Call downloadFile
const response =  await downloadFile(options);
return response.promise.then(async res => 
  //Transform response
  if(res && res.statusCode === 200 && res.bytesWritten > 0 &&
  res.path){
    doSomething(res)
  }else{
    logError(res)
}};
Enter fullscreen mode Exit fullscreen mode

The response from downloadFile contains statusCode , jobId and bytesWritten . To know if a request is successful, check whether the statusCode is 200 and the bytesWritten > 0. It is important to check both values because, I found it returning 200 even when no files were written.

I saved the path in the Redux's state to later retrieve the file.

Opening the saved file in a WebView

Install react-native-webview:

yarn add react-native-webview
Enter fullscreen mode Exit fullscreen mode

or

npm install react-native-webview
Enter fullscreen mode Exit fullscreen mode

Again, install the CocoaPods dependencies (iOS specific):

cd ios && pod install
Enter fullscreen mode Exit fullscreen mode

Implementing the WebView:

Create a React Funcional Component containing a WebView .

const WebViewComponent: React.FunctionComponent = ({ navigation, route}: any): JSX.Element => (
<WebView
  source={{ uri: "file://"+ path}}
  style={{ flex: 1 }}
  originWhitelist={["*"]}
/>
)};
export default WebViewComponent;
Enter fullscreen mode Exit fullscreen mode

The WebView source's URI should point to file:// + pathToFile . Don't forget to include the style property and set flex:1 as shown above.

Top comments (6)

Collapse
 
ribath profile image
Mohammad Ribath

it shows my file is downloaded in the console. I can access the image by filepath and set it to a imageview also. but why dont I see it in m gallery? where to find the downloaded files if I need to access it by file manager?

Collapse
 
amankumarsingh01 profile image
A

Hello, thanks for sharing. 👍

If you would like to add syntax coloring to your code:

Markdown - how to make blocks of React code (syntax highlighting - github, dev.to)

I personally struggeled with this.

At the beginning of the src code line after 3 x the grave accent sign, we need to add jsx.

This is React code sample:

import React from "react";

const App = () => {
  return (
    <div>
      <h1>My App</h1>
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode
Collapse
 
johannawad profile image
Johanna

Thanks for your suggestion. It will definitely improve the readability of the code!

Collapse
 
peterlunch profile image
Peter

Great post just helped me thanks.

Collapse
 
rayanwilbert profile image
Rayan Melino Wilbert

I appreciate it!

Collapse
 
yrancillac profile image
Yannick

Thanks for the post.
Could you please provide a github link?