Reputation: 47
I'm trying to make a simple firebase to-do app. I can write todos, no problem. However, when I try to delete a todo or mark one as complete, it seems the id
is undefined
, and firebase can't find the to-do in question. How can I correct this? For context, I am following this tutorial: https://www.youtube.com/watch?v=cuvP4h6O2x8&t=755s
Code:
import "../App.css";
import {useState} from "react";
import {auth, firestore} from "../firebase";
import firebase from "../firebase";
import {useCollectionData} from "react-firebase-hooks/firestore";
const Todos = () => {
const [todo, setTodo] = useState("");
const todosRef = firestore.collection(`users/${auth.currentUser.uid}/todos`);
const [todos] = useCollectionData(todosRef, { idField: "id" });
const signOut = () => auth.signOut();
const onSubmitTodo = (event) => {
event.preventDefault();
setTodo("");
todosRef.add({
text: todo,
complete: false,
createdAt: firebase.firestore.FieldValue.serverTimestamp(),
});
};
return (
<>
<header>
<button onClick = {signOut}>Sign Out</button>
</header>
<main>
<form onSubmit = {onSubmitTodo}>
<input
required
value = {todo}
onChange = {(e) => setTodo(e.target.value)}
placeholder="what's next?"
/>
<button type="submit"> Add </button>
</form>
{todos && todos.map((todo)=> <Todo key={todo.id} {...todo} />)}
</main>
</>
);
};
const Todo = ({ id, complete, text}) => {
const todosRef = firestore.collection(`users/${auth.currentUser.uid}/todos`);
const onCompleteTodo = (id, complete) =>
todosRef.doc(id).set({ complete: !complete }, { merge: true });
const onDeleteTodo = (id) => todosRef.doc(id).delete();
return (
<div key={id} className="todo">
<button
className={`todo-item ${complete ? "complete" : ""}`}
tabIndex="0"
onClick={()=> onCompleteTodo(id, complete)}
>
{text}
</button>
<button onClick={() => onDeleteTodo(id)}>x</button>
</div>
);
};
export default Todos;
Upvotes: 0
Views: 1038
Reputation: 1
Go to rules and type edit with following code:
allow read, write: if request.time>timestamp.date(2022, 11, 23);
Upvotes: 0
Reputation: 1994
React Firebase Hooks v5 matches Firebase 9 and above, in which you should use the FirestoreDataConverter
interface.
See the documentation.
The examples use TypeScript, but in your case something like this should work, applying withConverter
and your custom converter right after getting the collection:
const converter = {
toFirestore(post) {
return {
text: post.text,
}
},
fromFirestore(snapshot, options) {
const data = snapshot.data(options)
return {
id: snapshot.id,
text: data.text,
}
},
}
const todosRef = firestore
.collection(`users/${auth.currentUser.uid}/todos`)
.withConverter(converter);
Upvotes: 2