Firestore 分页,怎么做?

Firestore Pagination, how to?

我似乎无法完全理解这是如何完成的。不要认为文档解释得很好,或者我只是不明白:)

我想要做的是有一个列表,从显示 X 项开始。然后单击按钮加载集合中的下 X 个项目...

我创建了这个我可以调用的通用函数:

let latestDoc = null;

export const getDocumentsPaginated = async <T extends { id?: string }>(collectionPath: string, numberOfDocs: number) => {
  const items: T[] = [];
  const q = query(collection(db, collectionPath), orderBy('createdAt', 'desc'), startAfter(latestDoc || 0), limit(numberOfDocs));
  const querySnapshot = await getDocs(q);
  console.log('querySnapshot', querySnapshot)
  latestDoc = querySnapshot.docs[querySnapshot.docs.length - 1];
  querySnapshot.forEach((doc) => {
    const data = doc.data();
    items.push({
      ...data,
      id: doc.id
    } as T);
  });

  return items;
};

然后尝试从 Vue 组件调用它:

const fetchExercises = async () => {
      isLoading.value = true;
      try {
        const result = await getDocumentsPaginated<ExerciseDocument>(`exercises/${companyId}/exercises`, 5);
        console.log('internal', result);
        exercises.value = result;
        isLoading.value = false;
      } catch (e) {
        throw new Error('cant load exercises ' + e);
      }
    };

这似乎不起作用。即使我知道集合中有很多文档,我还是得到一个空数组?

我做错了什么?真的要伸出援手

Firestore 分页 基于偏移量工作,因此您将 20 添加到计数器将不起作用(如您所见)。


Firestore 分页基于 cursors object。这意味着要查询第二页的文档,您必须知道第一页最后一项的数据。

因为你 orderBy('createdAt', 'desc'),你需要知道第一页最后一个文档的 createdAt 值(和文档 ID),并将这些传递给 startAfter获取第二页的文档。


在 Firestore 中进行分页的最简单方法是将当前页面最后一项的 DocumentSnapshot 保存在一个变量中,例如:

const querySnapshot = await getDocs(q);
lastDocumentOnCurrentPage = querySnapshot.docs[querySnapshot.docs.length-1];

然后当你需要加载下一页数据时,将这个变量传递给查询的startAfter条件。