5

I have a React Native app in which at some page I've got a web view (react-native-webview) for displaying PDFs from our server.

In iOS everything works fine, in Android, whenever I try to view the file I got:

Cannot downoad files as permission was denined. Please provide permission to write to storage, in order to download files.

I've then added <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> to my manifest. Now, I'm getting the following alert:

enter image description here

I think it's pretty scary and very stupid from a user experience perspective. I'm not accessing photos, media, or files, all I'm trying to do is to display a simple PDF inside a web view. I don't want my users to be presented such alert.

When I tap allow, it says Downloading... and downloads the PDF like a file that can be opened outside my app. I don't want this behavior, I want PDF to render inside web view just like iOS does.

How can I display PDFs in Android using React Native web view, without a scary dialog which has nothing to do with what I'm actually trying to do?

(I'm on React Native 0.59.9, Android 8.1, Android SDK 28, react-native-web-view 5.12.0)

Can Poyrazoğlu
  • 33,241
  • 48
  • 191
  • 389
  • I remember appending pdf urls to google doc viewer url in order to display them in RN webview on Android. Like so `https://docs.google.com/gview?embedded=true&url=`. Files getting downloaded could be because of `Content-Disposition: attachment` response header for pdf files. This header will force browser to download file first before allowing to view content. – Amar Jul 11 '19 at 04:07
  • related link: https://github.com/facebook/react-native/issues/6488#issuecomment-291800918 – Amar Jul 11 '19 at 04:08
  • @Amar some of the PDFs are on a server that require authentication, not sure if embedding them that way would work. – Can Poyrazoğlu Jul 11 '19 at 08:01
  • Documents behind an auth might make it tricky. In that case, if you don't need a general document viewer may be you can use a pdf only solution, something like [react-native-pdf](https://github.com/wonday/react-native-pdf) – Amar Jul 11 '19 at 08:26
  • @Amar unfortunately I need a general document viewer. It can be HTML, PDF, or anything that a web view would normally open, may or may not be behind auth. I don't know the contents in advance, all I know is that I have the auth and it's a document. – Can Poyrazoğlu Jul 11 '19 at 09:28

2 Answers2

4

After trying various things I've given up on displaying PDFs directly and converting it to HTML. There's apparently no reliable way to display PDFs in default browser (viewing PDF directly might work on some machines but definitely not reliable as it didn't on my device/emulators).

Can Poyrazoğlu
  • 33,241
  • 48
  • 191
  • 389
0

Observed this issue in "react": "17.0.2", "react-native": "0.66.3", & i was using react-native-webview

  • react-native-webview cannot directly allow pdf rendering, you can do work around, you can use gview [base_url][1] for that.
    for example https://docs.google.com/gview?embedded=true&url=http://www.elpregonero.info/PARTITURA/PDF/619%20-%20the%20beatles%20%20-%20something.pdf

  • and then render it in webview as below
    import { WebView as Webs } from "react-native-webview";
    <Webs originWhitelist={["*"]} allowFileAccess={true} allowUniversalAccessFromFileURLs={true} source={{uri:${your_base_url_mentioned_above}}} style={styles.webViewer} //do not forget flex:1 in style />

  • In-order to make above mentioned hack to work, your url should have .pdf as extension

  • if its not there then use another hack,

  • download pdf from your url & then render it.

  • inorder to do that you can use below packages rn-fetch-blob to download the file from url & then use react-native-pdf to render it(you have to get the path of the file & then you have to provide).

  • but rn-fetch-blob is not maintained i guess, use some-other packages like react-native-fs to download the file.

  • There is no way webview will handle pdf directly in android.

abhish
  • 243
  • 4
  • 8