Firebase 不在 useCollectionData 中返回 ID

Firebase not returning ID in useCollectionData

我正在尝试制作一个简单的 firebase 待办事项应用程序。我可以写待办事项,没问题。但是,当我尝试删除待办事项或将待办事项标记为完成时,似乎 idundefined,并且 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 接口。

参见documentation

这些示例使用 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);