0

I am doing a covid app in react with firestore database. I am new to this firebase. For this app, I have created a collection in firestore named 'VaccinationCentre'. In that I have given 4 fields that are 'State,District,Centrename,NoofDose'.

Collection in firestore with 2 documents

I have attached an image where I have 2 cards for the 2 documents which I have added in the collection. My aim is to update the 'NoofDose' in each card by decreasing the value by 1 when ever the button 'apply' is clicked.For eg, if the NoofDose is 100 , after I click the button 'apply' it should show as 99 without manual refresh.I have tried but I was not able to update each document. I was not able to do that.I have inserted the code for your reference. Kindly help with this.

Output

function SearchVaccinCenter() {
    
    const history = useHistory();
    const auth = getAuth();
    const user = auth.currentUser;
    const db = getFirestore();
    const [data, setData] = useState([]);
    if (!user) {
        return <Redirect to="/login" />
    }
    function back() {
        history.push("/UserHome")
    }
    async function fetchdata() {
        const querySnapshot = await getDocs(collection(db, "VaccinationCentre"));
        const mapdata = querySnapshot.docs.map((e) => {
            
            return {
                centername: e.data().Centrename,
                district: e.data().District,
                state: e.data().State,
                noofdose: e.data().NoofDose,
                
            }
        })
        setData(mapdata);
        console.log(mapdata);
        
    }

    function ApplyForVaccination() {
        const database = getFirestore(); // initialize Firestore

        const docRef = doc(database, "VaccinationCentre", "Jtu2QyO1jxmhUl9mKZOc");
        console.log(doc.id);
        const data = {
            NoofDose: 50
        };

        updateDoc(docRef, data)
            .then(response => {
                console.log("Value of an Existing Document Field has been updated");
            })
            .catch(error => {
                console.log(error.message);
            })
    }

    return (

        <div style={{height:"600px"}}>
            <div className="continer">
                <nav  className="navbar navbar-light bg-dark">
                    <div  className="container-fluid">
                        <button style={{color:"white",backgroundColor:"grey"}} className="btn btn-outline-secondary" onClick={back}>Back</button>
                        <div className="d-flex">
                            <button style={{color:"white"}} type="button" className="btn btn-white">Hello {user.displayName}</button>
                        </div>
                        
                    </div>
                </nav>
                
            </div>
            <div style={{marginTop:"20px"}} className="col-md-12 text-center">
                <button className="btn btn-primary btn-lg" type="button" onClick={fetchdata}>Press to search</button>
                {data.map((element, index) => {
                return (
                    <div key={index} style={{width:"500px",margin:"50px 0px 0px 380px"}} className="card border-secondary mb-3">
                        <div style={{backgroundColor:"aliceblue"}}>
                            <h4 className="card-title ms-3"><b>No of Dose : {element.noofdose}</b></h4>
                            <div className="card-body">
                                <h6>State : {element.state}</h6>
                                <h6>District : {element.district}</h6>
                                <h6>Centre Name : {element.centername}</h6>   
                                {console.log(element.state)}
                                <button className="btn btn-success btn-sm" type="button" onClick={() => ApplyForVaccination()}>Apply</button> 
                            </div>
                        </div>
                    </div>
                )
            })}
            </div>
        </div>
    )
}

export default SearchVaccinCenter;
Moritz Ringler
  • 9,772
  • 9
  • 21
  • 34
  • "I was not able to do it" is really hard to help with. I recommend debugging your code locally, and telling us the outcome. If you set a breakpoint on each line of the code you shared, run the code in a debugger, and then check the value of each variable on each line, which is the **first** line that doesn't do what you expect it to do? – Frank van Puffelen Mar 14 '23 at 13:50
  • If you don't know how to increment/decrement a value, have a look at the documentation on the atomic increment/decrement operator: https://firebase.google.com/docs/firestore/manage-data/add-data#increment_a_numeric_value – Frank van Puffelen Mar 14 '23 at 13:51
  • In the above code , I mentioned specifically the id there to update [refer : initailize firestore in the above code].so the specific document is getting updated. But I want the id for each document to get passed.So, that I can able update whenever I click the 'apply' button[refer the apply button in the code]. – Vaishnavi S Mar 14 '23 at 16:07
  • If you're asking how to update all documents in a Firestore collection, see: https://stackoverflow.com/questions/51481192/firestore-update-all-documents-in-collections – Frank van Puffelen Mar 14 '23 at 18:24

1 Answers1

0

It seems like you want to update the document based on document id but when you load data with fetchdata() function. You are not saving the document id of each document in the data state.

I will recommend you to also add id field in your data state and use that to update the document as follows:

// Load data
async function fetchdata() {
    const querySnapshot = await getDocs(collection(db, "VaccinationCentre"));
    const mapdata = querySnapshot.docs.map((e) => {
        return {
// add the document ID to the data object so that you can update each document by sending this id
            id: e.id, // ⇐ saving id
            centername: e.data().Centrename,
            district: e.data().District,
            state: e.data().State,
            noofdose: e.data().NoofDose,    
        }
    })
    setData(mapdata);
    console.log(mapdata);    
}

And while updating just use that element.id and send element.noofdose as in your case you also want to decrement the NoofDose by 1.

//Update Document
function ApplyForVaccination(docId, currentNoOfDose) {
    const database = getFirestore();
// for safety also check if docId and currentNoOfDose is undefined or null
    const docRef = doc(database, "VaccinationCentre", docId);
    const data = {
        NoofDose: currentNoOfDose - 1
    };

    updateDoc(docRef, data)
        .then(response => {
            console.log("Value of an Existing Document Field has been updated");
        })
        .catch(error => {
            console.log(error.message);
        })
}

And then call ApplyForVaccination() as follows:

<button className="btn btn-success btn-sm" type="button" onClick={() => ApplyForVaccination(element.id, element.noofdose)}>Apply</button>

In this way you can update the document. But after the update you need to run the fetchdata() functions again to reflect the latest data in your UI.

If you want realtime update occur in your UI then use onSnapshot

Rohit Kharche
  • 2,541
  • 1
  • 2
  • 13