4

I am using the react-native-pdf-view library and I am having trouble populating the PDFView with a pdf.

How my project works is that I receive a base64 pdf from the server where I then save to the android file system by using the library react-native-fs like so:
(This works fine)

saveFile(filename){

   var base64Image = this.state.imageBase64;

   // create a path you want to write to
   var path = RNFS.DocumentDirectoryPath + '/' + filename;

   // write the file
   RNFS.writeFile(path, base64Image, 'base64').then((success) => {
     console.log('FILE WRITTEN!');
     this.setState(
       {pdf_dirPath: path}
     );
     this._display_fileAttachment()
   })
   .catch((err) => {
     console.log(err.message);
   });
 }

I then try populate the pdf view with this:

<PDFView
  ref={(pdf)=>{this.pdfView = pdf;}}
  src={"path/To/base64/pdf"}
  style={styles.pdf}
 />

Question

Does the react-native-pdf-view have to take a file location or can it take a base64 pdf or a blob.

If it can take a base64 or blob please explain or give sample code on how to do it.
Thanks

Nb: This StackOverflow question is very similar but I need to know how in what form to save or retrieve the base64 from the file system and how to populate the pdf.

Community
  • 1
  • 1
Larney
  • 1,674
  • 4
  • 23
  • 47
  • 1
    looking as the [source-code](https://github.com/cnjon/react-native-pdf-view/blob/master/RNPDFView/RNPDFView.m#L56), it doesn't appear to accept base64, you will have to provide a path. To troubleshoot this, I would `console.log` the `path/to/pdf` to confirm that it saved and is a good PDF. – Kyle Finley Aug 01 '16 at 03:38
  • @Kyle Finley Thanks for pointing that out. The problem seems to be saving the file. Check out this post for more details. http://stackoverflow.com/questions/38662309/how-to-save-pdf-to-android-file-system-react-native Thanks. – Larney Aug 02 '16 at 08:37

2 Answers2

3

It seems like there's a much easier way to do this. Just tell RNFletchBlob to save directly to disk like so. Note that you'll have to clean up the file later.

RNFetchBlob
  .config({
    // add this option that makes response data to be stored as a file. 
    fileCache : true,
    appendExt : 'pdf'
  })
  .fetch('GET', 'http://www.example.com/file/example.zip', {
    //some headers ..
  })
  .then((res) => {
    // the temp file path 
    this.setState({fileLocation: res.path()});
    console.log('The file saved to ', res.path())
  })

And then later

<PDFView 
  ref={(pdf)=>{this.pdfView = pdf;}}
  path={this.state.fileLocation}
  onLoadComplete = {(pageCount)=>{
    this.pdfView.setNativeProps({
      zoom: 1.0
    });
    console.log("Load Complete. File has " + pageCount + " pages.");
  }}
  style={styles.pdf}/>
Pedram
  • 7,479
  • 6
  • 25
  • 25
2

For anyone having the same problem, here is the solution. Solution

react-native-pdf-view must take the file path to the pdf_base64.

Firstly, I used the react-native-fetch-blob to request the pdf base64 from the server. (Because RN fetch API does not yet support BLOBs).

Also, I discovered that react-native-fetch-blob also has a FileSystem API which is way better documented and easier to understand than the 'react-native-fs' library. (Check out its FileSystem API documentation)

Receiving base64 pdf and saving it to a file path:

var RNFetchBlob = require('react-native-fetch-blob').default;

const DocumentDir = RNFetchBlob.fs.dirs.DocumentDir;

getPdfFromServer: function(uri_attachment, filename_attachment) {
   return new Promise((RESOLVE, REJECT) => {

      // Fetch attachment
      RNFetchBlob.fetch('GET', config.apiRoot+'/app/'+uri_attachment)
      .then((res) => {
       
          let base64Str = res.data;
          let pdfLocation = DocumentDir + '/' + filename_attachment;

          RNFetchBlob.fs.writeFile(pdfLocation, pdf_base64Str, 'base64');
          RESOLVE(pdfLocation);
      })
   }).catch((error) => {
       // error handling
       console.log("Error", error)
   });
}

What I was doing wrong was instead of saving the pdf_base64Str to the file location as I did in the example above. I was saving it like this:

var pdf_base64= 'data:application/pdf;base64,'+pdf_base64Str;

which was wrong.

Populate PDF view with file path:

<PDFView
    ref={(pdf)=>{this.pdfView = pdf;}}
    src={pdfLocation}
    style={styles.pdf}
/>
        
yash rathod
  • 53
  • 10
Larney
  • 1,674
  • 4
  • 23
  • 47
  • What is that "RESOLVE" function? It doesn't seem to be defined anywhere, and gave me an error when I tried to run your code. – Pedram Oct 19 '16 at 19:31
  • @Pedram "Resolve() returns a Promise object that is resolved with the given value." - https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise – Larney Oct 19 '16 at 20:29
  • Oh I see. That's just the callback that gets passed in to be executed when your promise gets resolved. – Pedram Oct 20 '16 at 15:35