Firebase 不在 useCollectionData 中返回 ID
Firebase not returning ID in useCollectionData
我正在尝试制作一个简单的 firebase 待办事项应用程序。我可以写待办事项,没问题。但是,当我尝试删除待办事项或将待办事项标记为完成时,似乎 id
是 undefined
,并且 firebase 无法找到有问题的待办事项。我该如何纠正这个问题?对于上下文,我遵循本教程:https://www.youtube.com/watch?v=cuvP4h6O2x8&t=755s
代码:
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;
React Firebase Hooks v5 匹配 Firebase 9 及更高版本,您应该在其中使用 FirestoreDataConverter
接口。
这些示例使用 TypeScript,但在您的情况下,这样的事情应该可行,在获取集合后立即应用 withConverter
和您的自定义转换器:
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);
我正在尝试制作一个简单的 firebase 待办事项应用程序。我可以写待办事项,没问题。但是,当我尝试删除待办事项或将待办事项标记为完成时,似乎 id
是 undefined
,并且 firebase 无法找到有问题的待办事项。我该如何纠正这个问题?对于上下文,我遵循本教程:https://www.youtube.com/watch?v=cuvP4h6O2x8&t=755s
代码:
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;
React Firebase Hooks v5 匹配 Firebase 9 及更高版本,您应该在其中使用 FirestoreDataConverter
接口。
这些示例使用 TypeScript,但在您的情况下,这样的事情应该可行,在获取集合后立即应用 withConverter
和您的自定义转换器:
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);