Heim  >  Fragen und Antworten  >  Hauptteil

Ich versuche, eine Liste mit Download-Links aus dem Firebase-Speicher abzurufen, um sie in meiner React/nextjs-Komponente anzuzeigen

Beim Versuch, das Array abzurufen, sind die Daten immer leer. Weiß jemand, wo ich falsch liege? Ich habe die Konsole überprüft und soweit ich das beurteilen kann, gibt es einen Verweis auf den Firebase-Speicher, aber keine Daten. In meinem Speicher befinden sich jedoch 4 Dokumente, die URL-Links ausgeben sollen. Das ist meine Komponente

import React, { useState, useEffect } from 'react';

// i'm initializing firebase with firebase.initializeApp(firebaseConfig)
import { projectStorage } from '@/firebaseConfig'; 
 // projectStorage is =         firebase.storage();


const PDFViewer = () => {
  const [pdfUrls, setPdfUrls] = useState();

  useEffect(()=>{
   const storageRef = projectStorage.ref();
   const pdfRef = storageRef.child('myfirebaselocationpath/uploadeddocs/'); 
   const urls = [];
   pdfRef.listAll().then((result) => {
    result.items.forEach((itemRef) => {
    itemRef.getDownloadURL().then((url) => {
      urls.push(url);
    });
  });
  setPdfUrls(urls);
}).catch((error) => {
  console.error('Error retrieving PDF files:', error);
});
},[])
console.log(pdfUrls)
/*  console.log( pdfUrls.map((url) => {
return url
 })
) */
return (
<div>
  <h1>PDF Viewer</h1>
  {pdfUrls.map((url) => (
    <iframe key={url} src={url} width="100%" height="600px" />
  ))}
</div>
 );
};

export default PDFViewer;`

Die obige Komponente ist das, was ich versucht und erwartet habe, eine verknüpfte Liste von Karten, aber es wurden keine Daten angezeigt. Und pdfUrls ist immer leer.

P粉481035232P粉481035232400 Tage vor725

Antworte allen(1)Ich werde antworten

  • P粉976488015

    P粉9764880152023-09-16 14:36:26

    问题出在这里:

    pdfRef.listAll().then((result) => {
      result.items.forEach((itemRef) => {
      itemRef.getDownloadURL().then((url) => {
        urls.push(url);
      });
    });
    setPdfUrls(urls);

    listAllgetDownloadURL 都是异步操作,可能需要一些时间才能完成。主代码不会阻塞整个脚本,而是在操作发生时继续执行 - 然后当数据(文件列表或下载 URL)可用时执行回调块。

    这意味着您的 setPdfUrls(urls); 在任何 urls.push(url); 运行之前运行,并且这会设置一个空列表。我建议在调试器中检查这一点,或者添加一些日志记录。


    解决该问题的最简单方法是将 setPdfUrls(urls); 移至内部回调:

    pdfRef.listAll().then((result) => {
      result.items.forEach((itemRef) => {
      itemRef.getDownloadURL().then((url) => {
        urls.push(url);
        setPdfUrls(urls);
      });
    });

    现在它会在确定每个下载 URL 后调用。这会执行多次更新,因此可能会导致 UI 中出现一些闪烁,但数据现在应该会显示。


    在等待一切完成的同时只调用一次 setPdfUrls(urls); 需要做更多的工作。最简单的方法可能是将整个 useEffect 处理程序标记为 async 并在其中使用 await

    useEffect(() => async {
      const storageRef = projectStorage.ref();
      const pdfRef = storageRef.child('myfirebaselocationpath/uploadeddocs/');
      const urls = [];
      const result = await pdfRef.listAll();
      for (const itemRef of result.items) {
        const url = await itemRef.getDownloadURL();
        urls.push(url);
      }
      setPdfUrls(urls);
    }, [])

    所以这段代码:

    • 使用 await 确保异步操作在调用 setPdfUrls 之前完成。
    • 使用 for...of 循环来确保我们可以在该循环内使用 await

    Antwort
    0
  • StornierenAntwort