Home > Software engineering >  How do I get first call to Firebase to work?
How do I get first call to Firebase to work?

Time:05-11

Every time I reload my web app the first time I try call getDBRecords() it doesn't work (the code inside the then statement doesn't execute), but then if I try again immediately it will work, and will continue to work from then on until I reload the app.

How can I get the DB call to work first time? Is it something to do with Promises /Async await?

Any help is much appreciated!

firebase.js Installation/Configuration

    import * as firebase from 'firebase'
    
    const firebaseConfig = {
        apiKey: "",
        authDomain: "",
        projectId: "",
        storageBucket: "",
        messagingSenderId: "",
        appId: "",
        measurementId: "",
        databaseURL: ""
      };
    
    let app
    if (firebase.apps.length === 0) {
        app = firebase.initializeApp(firebaseConfig)
      } else {
        app = firebase.app();
      }
    
    const auth = firebase.auth()
    const db = firebase.firestore();
    export { db, auth };

DataContext

import React, { useContext, useState, useEffect } from 'react'
import { db } from '../../firebase'

const DataContext = React.createContext()

export function useData() {
    return useContext(DataContext)
}
export function DataProvider({ children }) {
    const [result, setResult] = useState('')

    function getDBRecords() {
        setResult('')
        var results = []
        
        var promise = db.collection("COLLECTION_NAME").where("attr", ">", 10).get()
        
        promise.then((querySnapshot) => {
            querySnapshot.forEach((doc)=>{
                results.push(doc.data())
            })
            setResult(results)
        }).catch((error) => {
            console.log("Error getting document:", error);
        });
        return result
    }
    const value = {
            testDBRead,
            testDBWrite,
            getLastFew,
            propSearch
        }
    return (
            <DataContext.Provider value={value}>
                {children}
            </DataContext.Provider>
        )

CodePudding user response:

You should call your function in useEffect

useEffect(() => {
    getDBRecords();
},[])

CodePudding user response:

Figured it out, posting the answer for anyone else who runs into the problem.

I needed to give the then() function after the promise a function it could callback, I think, not sure how it works but by passing the useState set state function into my useContext() and calling that function inside my then function the data is updated.

In the screen.js file:

    // Importing the function from a useContext
    const { fetchSingleDoc } = useData()
    const [doc, setDoc] = useState('')

    // Here I call the fetchSingleProp and pass both the ID of the document I wish to get and the setter function.
    const handleFetchDoc = (doc_id) => {
        console.log("Fetching Property: ", x)
        fetchSingleProp(doc_id, setDoc)
    }

In the DataContext.js file:

// The solution for me was to add the setDoc function and call it inside the then call.
function fetchSingleDoc(prop_id, setDoc) {
        var propRef = db.collection("PROD-JOIN").doc(props[prop_id]);
        propRef.get().then((doc) => {
            if (doc.exists) {
                const data = doc.data()

                setDoc(data)
            } else {
                console.log("No such document!");
            }
        }).catch((error) => {
            console.log("Error getting document:", error);
        });
    }

Not really sure whats happening but I think the then part of the statement hasnt returned and so needs a function it can "call back" to pass the value back to the right place.

  • Related