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
条件。
我似乎无法完全理解这是如何完成的。不要认为文档解释得很好,或者我只是不明白:)
我想要做的是有一个列表,从显示 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
条件。