Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

479
Visualizações
React: Button to export data from Firebase Firestore database

I am trying to make a button in my React web application which exports either all data or preferably specific collections from Firebase Cloud Firestore database as JSON.

Below is what I'm working with currently. This sort of works but not properly. When I click the button and download the JSON, it will be empty because the data wasn't loaded yet. When I click the button the second time and download the JSON again, it will have the desired data because it was loaded after the first click. I have tried different async and Promise structures to wait for all the data before starting the download but so far I have failed. The data could always be downloaded pre-hand with useEffect but this is not an option because it extremely increases the Firebase calls made with the application.

How do you properly wait for all the data before downloading it? Is there some different way to achieve this?

function App() {
    const [download, setDownload] = useState([])
    const downloadLink = useRef()

    const downloadMyCollection = async () => {
        const myCollection = collection(db, 'myCollection')
        const data = await getDocs(myCollection)
        setDownload(data.docs.map((doc) => ({...doc.data(), id: doc.id})))
        downloadLink.current.click()
    }

    return (
        <div>
            <button
                className="downloadButton"
                onClick={ downloadMyCollection }>
                Download Responses
            </button>

            <a
                href={`data:text/json;charset=utf-8,${encodeURIComponent(
                    JSON.stringify(download)
                )}`}
                download='export.json'
                className='hidden'
                ref={downloadLink}>
                isHidden
            </a>
        </div>
    )
}
about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

I don't know 100% if this will work, the fact is that setState Hook is asyncronous, so even setDownload will run before the click, the download state will be an empty array when the click() event run.

My suggestion is to create an Hooks that listen to download state, and check if isn't empty and then fire the click event.

function App() {
    const [download, setDownload] = useState([])
    const downloadLink = useRef()

    const downloadMyCollection = async () => {
        const myCollection = collection(db, 'myCollection');
        const data = await getDocs(myCollection);
        setDownload(data.docs.map((doc) => ({...doc.data(), id: doc.id})))
    };

    useEffect(() => {
     if(!!download.length) downloadLink.current.click();
    },[download]}

    return (
        <div>
            <button
                className="downloadButton"
                onClick={ downloadMyCollection }>
                Download Responses
            </button>

            <a
                href={`data:text/json;charset=utf-8,${encodeURIComponent(
                    JSON.stringify(download)
                )}`}
                download='export.json'
                className='hidden'
                ref={downloadLink}>
                isHidden
            </a>
        </div>
    )
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda