如何使用React-PDF从React中的Firebase存储中查看PDF DOC?

发布于 2025-01-31 23:51:52 字数 595 浏览 4 评论 0原文

我想从我的React应用中的Firebase存储中查看PDF文件,问题是我想在加载页面后查看该文件,并且“ GetDownloadurl” Firebase方法是异步。

我试图做这样的事情:

    const MyPage = (props) => {
      const [numPages, setNumPages] = useState(null)
      const [pageNumber, setPageNumber] = useState(1)
      const [url, setURL] = useState('')
    
     const showFile = async () => {
        return await storage.ref(props.props.sheetMusicRef).getDownloadURL()
      }
    
    return   <Document file={showFile}>
              <Page pageNumber={pageNumber} />
            </Document>
}

没有成功。

I would like to view a pdf file from firebase storage in my React app, the problem is I would like to view the file after the page is loaded and the 'getDownloadURL' firebase method is async.

I tried to do something like this:

    const MyPage = (props) => {
      const [numPages, setNumPages] = useState(null)
      const [pageNumber, setPageNumber] = useState(1)
      const [url, setURL] = useState('')
    
     const showFile = async () => {
        return await storage.ref(props.props.sheetMusicRef).getDownloadURL()
      }
    
    return   <Document file={showFile}>
              <Page pageNumber={pageNumber} />
            </Document>
}

with no success.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

好多鱼好多余 2025-02-07 23:51:52

今天我做了类似的事情,我想简单地从firebase存储中获取PDF,同时显示加载程序,然后渲染文件。我决定不要为自己的用例中使用React-PDF,因为我想在整个视口上嵌入文件。如果您想专门查看我建议的解决方案,请跳到下一个标题。

我的解决方案

此组件从Firebase存储中获取PDF,然后将文件嵌入整个视口上。为了确保我没有能够滚动或下面滚动的能力,可以模仿浏览器中直接打开文件的行为,我使用了NPM的“身体旋转锁” - 包装。我还将MUI用于样式组件。因此,如果您任何人都来此帖子并想要一个工作的全屏PDF浏览器,从firebase存储中获取PDF并显示加载程序,那么您就可以了:

import React from "react";
import { Box, Typography, useMediaQuery } from "@mui/material";
import { FC, useEffect, useState } from "react";
import { useTheme } from "../ThemeProvider";
import { disableBodyScroll, clearAllBodyScrollLocks } from "body-scroll-lock";
import { Seek } from "react-loading-indicators";
import { getDownloadURL, ref } from "firebase/storage";
import { storage } from "../firebaseConfig";

const LandingPage: FC = (props) => {
  const targetRef = React.createRef();
  const [isLoading, setIsLoading] = useState(true);
  const [pdf, setPdf] = useState(null);

  useEffect(() => {
    disableBodyScroll(targetRef);

    getDownloadURL(ref(storage, "firebase_storage_path.pdf"))
      .then((url) => {
        setPdf(url);
        setInterval(() => setIsLoading(false), 500);
      })
      .catch(() => setIsLoading(false));

    return () => {
      clearAllBodyScrollLocks();
    };
  }, []);

  return (
     <Box
     ref={targetRef}
     display="flex"
     justifyContent="center"
     alignItems="center"
     sx={{
       height: "100vh",
       width: "100vw",
     }}
   >
     {isLoading ? (
       <Seek color="#000" size="small" />
     ) : !pdf ? (
       <Typography variant="h4">Oops, something went wrong</Typography>
     ) : (
       <embed type="application/pdf" width="100%" height="100%" src={pdf} />
     )}
   </Box>
  );
};
export default LandingPage;

解决问题的解决方案,具体来说,

我已经修改了您提供的代码,并且提出了一些可以按照您想要的方式奏效的更改。这显示了一个加载程序,同时获取文件,从firebase存储中获取文件,并显示出错误消息是否出了问题,或使用React-PDF加载PDF。

import { useEffect, useState } from "react";
import React from "react";
import { Seek } from "react-loading-indicators";
import { getDownloadURL, ref } from "firebase/storage";
import { storage } from "../firebaseConfig";
import { Document, Page } from "react-pdf";

const MyPage = (props) => {
  const [numPages, setNumPages] = useState(null);
  const [pageNumber, setPageNumber] = useState(1);
  const [isLoading, setIsLoading] = useState(true);
  const [url, setURL] = useState(null);

  useEffect(() => {
    getDownloadURL(ref(storage, "firebase_storage_path.pdf"))
      .then((url) => {
        setURL(url);
        // Could include a way of updating numPages here
        setInterval(() => setIsLoading(false), 500); // Just for the sake of showing the loader
      })
      .catch(() => setIsLoading(false));

    return () => {};
  }, []);

  if (isLoading) return <Seek color="#000" size="small" />; // Show loader
  else {
    if (!url)
      return <p>Oops, something went wrong</p>; // If catched error from fetch
    else
      return (
        <Document file={url}>
          <Page pageNumber={pageNumber} />
        </Document>
        // Could also include a way of switching page number based on numPages
      );
  }
};
export default MyPage;

I did something similar today, where I wanted to simply fetch a pdf from Firebase Storage, show a loader in the meantime, and render the file. I decided to not go for react-pdf for my own use case, as I wanted to embed the file over the whole viewport. Skip to the next header if you want to see my proposed solution to your code specifically.

My solution

This component fetches the pdf from Firebase Storage, before embedding the file over the whole viewport. For making sure that I do not get the ability to scroll over or under, mimicing the behavior of opening a file straight in the browser, I utilize the "body-scroll-lock"-package from npm. I also use MUI for styled components. So, if you anyone comes onto this post and want a working full screen pdf-viewer, fetching the pdf from Firebase Storage and showing a loader, here you go:

import React from "react";
import { Box, Typography, useMediaQuery } from "@mui/material";
import { FC, useEffect, useState } from "react";
import { useTheme } from "../ThemeProvider";
import { disableBodyScroll, clearAllBodyScrollLocks } from "body-scroll-lock";
import { Seek } from "react-loading-indicators";
import { getDownloadURL, ref } from "firebase/storage";
import { storage } from "../firebaseConfig";

const LandingPage: FC = (props) => {
  const targetRef = React.createRef();
  const [isLoading, setIsLoading] = useState(true);
  const [pdf, setPdf] = useState(null);

  useEffect(() => {
    disableBodyScroll(targetRef);

    getDownloadURL(ref(storage, "firebase_storage_path.pdf"))
      .then((url) => {
        setPdf(url);
        setInterval(() => setIsLoading(false), 500);
      })
      .catch(() => setIsLoading(false));

    return () => {
      clearAllBodyScrollLocks();
    };
  }, []);

  return (
     <Box
     ref={targetRef}
     display="flex"
     justifyContent="center"
     alignItems="center"
     sx={{
       height: "100vh",
       width: "100vw",
     }}
   >
     {isLoading ? (
       <Seek color="#000" size="small" />
     ) : !pdf ? (
       <Typography variant="h4">Oops, something went wrong</Typography>
     ) : (
       <embed type="application/pdf" width="100%" height="100%" src={pdf} />
     )}
   </Box>
  );
};
export default LandingPage;

The solution to your problem specifically

I have modified the code you have provided, and proposed some changes that would work the way you want it to. This shows a loader while fetching the file, fetches the file from Firebase Storage, and shows either an error message if something went wrong, or loads the pdf using react-pdf.

import { useEffect, useState } from "react";
import React from "react";
import { Seek } from "react-loading-indicators";
import { getDownloadURL, ref } from "firebase/storage";
import { storage } from "../firebaseConfig";
import { Document, Page } from "react-pdf";

const MyPage = (props) => {
  const [numPages, setNumPages] = useState(null);
  const [pageNumber, setPageNumber] = useState(1);
  const [isLoading, setIsLoading] = useState(true);
  const [url, setURL] = useState(null);

  useEffect(() => {
    getDownloadURL(ref(storage, "firebase_storage_path.pdf"))
      .then((url) => {
        setURL(url);
        // Could include a way of updating numPages here
        setInterval(() => setIsLoading(false), 500); // Just for the sake of showing the loader
      })
      .catch(() => setIsLoading(false));

    return () => {};
  }, []);

  if (isLoading) return <Seek color="#000" size="small" />; // Show loader
  else {
    if (!url)
      return <p>Oops, something went wrong</p>; // If catched error from fetch
    else
      return (
        <Document file={url}>
          <Page pageNumber={pageNumber} />
        </Document>
        // Could also include a way of switching page number based on numPages
      );
  }
};
export default MyPage;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文