React 和 Firebase Firestore V9 上一页分页返回 "first page"

React and Firebase Firestore V9 Previous Page Pagination returning to "first page"

我在这里不知所措。我觉得我一直在尝试一切,并使用其他 posts/tutorials 中解释的确切方法无处不在。我了解到您需要使用光标并设置第一个和最后一个可见文档,以便在向前移动的情况下可以在最后一个之后开始,在向后移动的情况下可以在第一个之前开始。

在我的实施中,前进工作正常。但是,当我使用 previousPage 函数时,尽管设置了 'first visible' 文档,但它 returns 我到了第一页。它 returns 到第一页,即使我已经向前移动了 3 'pages'。

显然这里有些东西我不明白..

  const PAGE_SIZE = 6;
  const [posts, setPosts] = useState([]);
  const [lastVisible, setLastVisible] = useState(null);
  const [firstVisible, setFirstVisible] = useState(null);
  const [loading, setLoading] = useState(false);

  // Initial read to get first set of posts. 
  useEffect(() => {
    const q = query(
      collectionGroup(db, "bulletins"),
      orderBy("createdAt", "desc"),
      limit(PAGE_SIZE)
    );
    const unsubscribe = onSnapshot(q, (documents) => {
      const tempPosts = [];
      documents.forEach((document) => {
        tempPosts.push({
          id: document.id,
          ...document.data(),
        });
      });
      setPosts(tempPosts);
      setLastVisible(documents.docs[documents.docs.length - 1]);
      setFirstVisible(documents.docs[0]);
    });
    return () => unsubscribe();
  }, []);

  const nextPage = async () => {
    const postsRef = collectionGroup(db, "bulletins");
    const q = query(
      postsRef,
      orderBy("createdAt", "desc"),
      startAfter(lastVisible),
      limit(PAGE_SIZE)
    );
    const documents = await getDocs(q);
    updateState(documents);
  };

  const previousPage = async () => {
    const postsRef = collectionGroup(db, "bulletins");
    const q = query(
      postsRef,
      orderBy("createdAt", "desc"),
      endBefore(firstVisible),
      limit(PAGE_SIZE)
    );
    const documents = await getDocs(q);
    updateState(documents);
  };

  const updateState = (documents) => {
    if (!documents.empty) {
      const tempPosts = [];
      documents.forEach((document) => {
        tempPosts.push({
          id: document.id,
          ...document.data(),
        });
      });
      setPosts(tempPosts);
    }
    if (documents?.docs[0]) {
      setFirstVisible(documents.docs[0]);
    }
    if (documents?.docs[documents.docs.length - 1]) {
      setLastVisible(documents.docs[documents.docs.length - 1]);
    }
  };

您应该使用 endAt() 而不是 endBefore(),并且您应该将 createdAt 的订单参考传递给 endAt() 方法。请参阅下面的代码:

  const PAGE_SIZE = 6;
  const [posts, setPosts] = useState([]);
  const [lastVisible, setLastVisible] = useState(null);
  const [firstVisible, setFirstVisible] = useState(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const q = query(
      collectionGroup(db, "bulletins"),
      orderBy("createdAt", "desc"),
      limit(PAGE_SIZE)
    );
    const unsubscribe = onSnapshot(q, (documents) => {
      const tempPosts = [];
      documents.forEach((document) => {
        tempPosts.push({
          id: document.id,
          ...document.data(),
        });
      });
      setPosts(tempPosts);
      setLastVisible(documents.docs[documents.docs.length - 1]);
      setFirstVisible(documents.docs[0]);
    });
    return () => unsubscribe();
  }, []);

  const nextPage = async () => {
    const postsRef = collectionGroup(db, "bulletins");
    const q = query(
      postsRef,
      orderBy("createdAt", "desc"),
      startAfter(lastVisible.data().createdAt), // Pass the reference
      limit(PAGE_SIZE)
    );
    const documents = await getDocs(q);
    updateState(documents);
  };

  const previousPage = async () => {
    const postsRef = collection(db, "bulletins");
    const q = query(
      postsRef,
      orderBy("createdAt", "desc"),
      endAt(firstVisible.data().createdAt), // Use `endAt()` method and pass the reference
      limitToLast(PAGE_SIZE)
    );
    const documents = await getDocs(q);
    updateState(documents);
  };

  const updateState = (documents) => {
    if (!documents.empty) {
      const tempPosts = [];
      documents.forEach((document) => {
        tempPosts.push({
          id: document.id,
          ...document.data(),
        });
      });
      setPosts(tempPosts);
    }
    if (documents?.docs[0]) {
      setFirstVisible(documents.docs[0]);
    }
    if (documents?.docs[documents.docs.length - 1]) {
      setLastVisible(documents.docs[documents.docs.length - 1]);
    }
  };

有关详细信息,请参阅 Add a simple cursor to a query