J'essaie d'extraire une liste de liens de téléchargement du stockage Firebase à afficher dans mon composant React/nextjs
P粉481035232
P粉481035232 2023-09-15 18:34:49
0
1
770

Lorsque vous essayez d'extraire le tableau, les données sont toujours vides. Est-ce que quelqu'un sait où je me trompe ? J'ai vérifié la console et pour autant que je sache, il y a une référence au stockage Firebase mais aucune donnée. Mais il y a 4 documents dans mon stockage qui devraient générer des liens URL. C'est mon composant

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

Le composant ci-dessus est ce que j'ai essayé et attendu, une liste chaînée de cartes, mais aucune donnée n'a été affichée. Et pdfUrls est toujours vide.

P粉481035232
P粉481035232

répondre à tous(1)
P粉976488015

Le problème est là :

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

listAllgetDownloadURL Ce sont toutes des opérations asynchrones et peuvent prendre un certain temps. Le code principal ne bloque pas l'intégralité du script, mais continue l'exécution pendant que l'opération se produit - puis exécute le bloc de rappel lorsque les données (liste de fichiers ou URL de téléchargement) sont disponibles.

Cela signifie que votre setPdfUrls(urls); 在任何 urls.push(url); est exécuté avant, et cela définit une liste vide. Je recommande de vérifier cela dans un débogueur ou d'ajouter de la journalisation.


Le moyen le plus simple de résoudre le problème est de passer setPdfUrls(urls); au rappel interne :

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

Maintenant, il sera appelé après que chaque URL de téléchargement soit déterminée. Cela effectuera plusieurs mises à jour, ce qui peut provoquer un scintillement dans l'interface utilisateur, mais les données devraient maintenant apparaître.


Ne l'appeler qu'une seule fois en attendant que tout soit terminé setPdfUrls(urls); 需要做更多的工作。最简单的方法可能是将整个 useEffect 处理程序标记为 async 并在其中使用 await demande plus de travail. Le moyen le plus simple est probablement de marquer l'intégralité du gestionnaire useEffect comme async et d'y utiliser 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);
}, [])

Donc ce code :

  • Utilisez await 确保异步操作在调用 setPdfUrls fait auparavant.
  • Utilisez for...of 循环来确保我们可以在该循环内使用 await.
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal