搜尋

首頁  >  問答  >  主體

我正在嘗試從 firebase 儲存中提取下載連結列表以顯示在我的 React/nextjs 元件中

當嘗試拉取陣列時,資料始終為空。有人知道我哪裡出錯了嗎? 我檢查了控制台,據我所知,有一個對 firebase 儲存的引用,但沒有資料。但我的儲存中有 4 個文件應該輸出 URL 連結。 這是我的元件

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;`

上面的元件是我嘗試過的,並期望映射連結列表,但沒有顯示任何資料。並且 pdfUrls 始終為空。

P粉481035232P粉481035232493 天前779

全部回覆(1)我來回復

  • 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

    回覆
    0
  • 取消回覆