Reputation: 43
import React, { useState } from 'react';
import { ref, onValue, update} from "firebase/database";
import { database } from '../../utils/firebase';
import './Card.css';
function Card(props) {
const [uid, setUID] = useState(props.uid);
function completeCard() {
const userRef = ref(database, 'users/' + uid);
onValue(userRef, (snapshot) => {
const data = snapshot.val();
var completedMissions = data["challenges"];
completedMissions.push(props.cardID);
const updates = {};
updates['/user/' + uid +'/challenges'] = completedMissions;
//This is the line causing the infinite loop
update(ref(database), updates);
});
}
return(
<div className="card">
<h1>{props.name}</h1>
<p>{props.description}</p>
<button onClick={completeCard}>Complete</button>
<button>+Info</button>
</div>
)
}
export default Card;
Hi, when I'm trying to update the value in the firebase real time database, it causes an infinite loop! I think that the onValue may be causing the problem but I don't know how to fix it. I would like when the button is pressed to only update the value once, as it only should change once, thank you in advance!
Upvotes: 2
Views: 540
Reputation: 84902
onValue
sets up a listener which will repeatedly call you back, every time that part of the database changes. So it gets data for the first time and runs your code. Your code updates the database, so the callback happens again, which causes you to update the database again. Repeat.
If you just want to get the value once, use get
instead:
import { ref, get, update } from "firebase/database";
//...
function completeCard() {
const userRef = ref(database, "users/" + uid);
get(userRef).then((snapshot) => {
const data = snapshot.val();
const completedMissions = data["challenges"];
completedMissions.push(props.cardID);
const updates = {};
updates["/user/" + uid + "/challenges"] = completedMissions;
update(ref(database), updates);
});
}
Or with async/await:
async function completeCard() {
const userRef = ref(database, "users/" + uid);
const snapshot = await get(userRef);
const data = snapshot.val();
const completedMissions = data["challenges"];
completedMissions.push(props.cardID);
const updates = {};
updates["/user/" + uid + "/challenges"] = completedMissions;
update(ref(database), updates);
}
Upvotes: 3