react-pdf image rendering with images stored in firebase storage

702 Views Asked by At

I've looked at as many posts as I could here and on GitHub, and none seemed to have a real solution. I am trying to render a pdf document using react-pdf that gets all the data it needs passed in by an object called model. In this case its a bunch of info about various hot tub models. The model object has an image object inside of it that has the urls to images of that specific hot tub. All of the urls are valid, but when I use the variable with the correct url in it I get the error: "TypeError: ctx.embedImage is not a function" and it will not display.

This is the component I'm using:

const PriceSheetDetails = ({ model }) => {
  const fontSource = process.env.REACT_APP_ADOBE_FONT_OTF;

  const imageUrl = model.image && model.image.url ? model.image.url.original : '';

  Font.register({ family: 'filson-pro', src: fontSource });

  const styles = StyleSheet.create({
    page: {
      backgroundColor: 'white',
      color: 'black',
    },
    section1: {
      padding: 20,
      backgroundColor: theme.color.red,
      fontFamily: 'filson-pro'
    },
    section2: {
      margin: 10,
      padding: 10,
    },
    title: {
      fontSize: '24px',
      color: 'white',
    },
    brand: {
      fontSize: '12px',
      color: theme.color.darkRed
    },
    viewer: {
      width: 1200,
      height: 1200,
      marginRight: 'auto',
      marginLeft: 'auto',
    },
  });

  return (
    <Grid pd={20} gg={8}>
      <Head2>Price Sheet Details</Head2>

      <Grid
        gtc='repeat(auto-fill, minmax(180px, 1fr))'
        ai='end'
        style={{ backgroundColor: theme.color.darkBlue025 }}
      >
        <PDFViewer style={styles.viewer}>
          <Document>
            <Page size='A4' style={styles.page}>
              <View style={styles.section1}>
                <Text style={styles.title}>
                  {model.title.toUpperCase()}
                </Text>
                <Text style={styles.brand}>
                  by {model.brand}
                </Text>
              </View>
              <View style={styles.section2}>
                <Image src={imageUrl} alt={model.image?.name || model.title} />
              </View>
            </Page>
          </Document>
        </PDFViewer>
      </Grid>
    </Grid>
  );
};

export default PriceSheetDetails;

I have tried two separate solutions I found that ended up not working.

  • The craco answers here did not work. I also tried the last answer given with this code:
function returnSrc() {
    const path = model.image.url.square_640;
    console.log("LOG", path);
    let selectedMethod = "GET";
    return { uri: path, method: selectedMethod, body: "", headers: "" };
  }

This solution does change the error to a CORS error, but my Firebase Storage rules are set up correctly to allow read and write from localhost.

  • I also inquired ChatGPT already, lol. It had me try to use the Base64 data by using this code:
const imageUrl = model.image && model.image.url ? model.image.url.original : '';

  const [imageData, setImageData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchImage = async () => {
      try {
        const response = await fetch(imageUrl);
        if (!response.ok) {
          throw new Error(response.statusText);
        }
        const arrayBuffer = await response.arrayBuffer();
        const base64 = btoa(
          new Uint8Array(arrayBuffer).reduce(
            (data, byte) => data + String.fromCharCode(byte),
            ''
          )
        );
        setImageData(`data:image/jpeg;base64,${base64}`);
      } catch (error) {
        setError(error.message);
      }
    };

    fetchImage();
  }, []);

This method then returns the same ctx.embedImage error I was getting while just passing the string directly into the src prop.

  • The answers here also seemed to not help, I've set up CORS rules and I cannot store images in the project in a public folder.
0

There are 0 best solutions below