How to show PDFs from Firebase Storage in React using react-pdf
In my recent project, I had to show a pdf from the firebase storage in the modal in react application. On my intital search react-pdf was the best result I got but as soon as I tried to implement I was stuck - the problem was firebase storage provided me a url of the pdf but it was not accepted by the react-pdf as I was not directly pointing towards the pdf it was reference url.
So after hours of searching and going through the documentation I got the solution - so as per the firebase storage documention it provides three functions to download data directly from the SDK such as getBlob(), getBytes() and getStream()
So I used the getBlob method to get the pdf data but before that you have to consfigure the CORS.
ps - to easily setup the cors just use gsutil cli and use the storage ref link to setup cors.
GetBlob function requires the ref path of the document and it return the blob data, store that in a variable.
Now we have to work pdf view compoent:
Import react-pdf:
import { pdfjs, Document, Page } from "react-pdf"; import "react-pdf/dist/Page/AnnotationLayer.css"; import "react-pdf/dist/Page/TextLayer.css";
Add globalworker at top:
pdfjs.GlobalWorkerOptions.workerSrc = new URL( "pdfjs-dist/build/pdf.worker.min.js", import.meta.url ).toString();
Inside the view-pdf compoent:
const [pdfString, setPdfString] = useState(""); const[numPages, setNumPages] = useState(0); const [pageNumber, setPageNumber] = useState(1); let base64String = useRef<any>(null); const onDocumentLoadSuccess = ({ numPages }: any) => { setNumPages(numPages); console.log("numPages: ", numPages); }; useEffect(() => { if (showModal) { let reader = new FileReader(); reader.readAsDataURL(data); reader.onloadend = () => { base64String.current = reader.result; setPdfString( base64String.current.substr(base64String.current.indexOf(",") + 1) ); }; } }, [showModal]); function changePage(offset: any) { setPageNumber((prevPageNumber) => prevPageNumber + offset); } function previousPage() { changePage(-1); } function nextPage() { changePage(1); }
Return will look like:
return( </div> {pdfString !== "" && ( <div className="w-full overflow-scroll h-96"> <Document file={`data:application/pdf;base64,${pdfString}`} onLoadSuccess={onDocumentLoadSuccess} > <Page renderAnnotationLayer={false} renderTextLayer={false} pageNumber={pageNumber} /> </Document> </div> )} <p className="mt-3"> Page {pageNumber || (numPages ? 1 : "--")} of {numPages || "--"} </p> <div className="mt-3 flex gap-4 "> {pageNumber > 1 && ( <button type="button" disabled={pageNumber <= 1} className="bg-blue-800 hover:bg-blue-700 text-white px-4 py-2 rounded" onClick={previousPage} > Previous </button> )} {pageNumber < numPages && ( <button type="button" disabled={pageNumber >= numPages} className="bg-blue-800 hover:bg-blue-700 text-white px-4 py-2 rounded" onClick={nextPage} > Next </button> )} </div> );
Some changes in global css:
.react-pdf__Page__canvas { margin: 0 auto; width: 100% !important; height: 100% !important; }
By now you can view your pdf file in react application, to further customize the pdf view read more.
Thanks for reading and comment any doubts or correction