我上周五从 分页持续问题提出了一个问题,因此 Firebase 文档有点令人困惑,所以我改进了我的代码,到 Firebase 分页文档。
这是我更新的代码:
async myForumQuestions(id: string, page = 1, pageSize =10): Promise<object> {
const refDocs = admin.firestore().collection("forum").orderBy("timeStamp").where("createdby", "==", id);
let lastDoc;
// If it's not the first page, get the last document from the previous page
if (page > 1) {
const skip = (page - 1) * pageSize - 1;
lastDoc = await refDocs.limit(skip).get().then((querySnapshot) => querySnapshot.docs[querySnapshot.docs.length - 1]);
}
const totalDocs = await refDocs.get().then((querySnapshot) => querySnapshot.size);
const totalPages = Math.ceil(totalDocs / pageSize);
// If there are no documents, return an empty list and set page and total_pages to 0
if (totalDocs === 0) {
return {
data: [],
pagination: {
page: 0,
total_pages: 0,
},
};
}
// Fetch the data with pagination
let myQuestionData;
if (lastDoc) {
myQuestionData = await refDocs.startAfter(lastDoc).limit(pageSize).get().then((querySnapshot) => querySnapshot.docs.map((doc) => doc.data() as ForumInterface));
} else {
myQuestionData = await refDocs.limit(pageSize).get().then((querySnapshot) => querySnapshot.docs.map((doc) => doc.data() as ForumInterface));
}
await Promise.all(
myQuestionData.map(async (question) => {
if (question.quoteId != undefined) {
const quotedSnapshot = await admin.firestore().collection("forum").doc(question.quoteId).get();
if (quotedSnapshot.exists) {
question.quoteData = quotedSnapshot.data() as ForumInterface;
} else {
question.quoteData = undefined;
}
}
})
);
return {
data: myQuestionData,
pagination: {
page: page,
total_pages: totalPages,
},
};
}
所以根据上面的代码,他们 Firebase 将根据
skipped
文档收费,这是我试图避免的..
所以基于光标基本分页,我想我可以使用文档的ID并按
timestamp
排序。
这是我更新的代码..
async allQuestions(cursor: string | null, pageSize =10): Promise<object> {
const refDocs = admin.firestore().collection("forum").orderBy("timeStamp");
let forumData;
// If there's a cursor, start after the cursor
if (cursor) {
forumData = await refDocs.startAfter(cursor).limit(pageSize).get().then((querySnapshot) => querySnapshot.docs.map((doc) => doc.data() as ForumInterface));
} else {
forumData = await refDocs.limit(pageSize).get().then((querySnapshot) => querySnapshot.docs.map((doc) => doc.data() as ForumInterface));
}
if (forumData.length === 0) {
return {
data: forumData,
cursor: null,
};
}
await Promise.all(
forumData.map(async (question) => {
if (question.quoteId != undefined) {
const quotedSnapshot = await admin.firestore().collection("forum").doc(question.quoteId).get();
if (quotedSnapshot.exists) {
question.quoteData = quotedSnapshot.data() as ForumInterface;
} else {
question.quoteData = undefined;
}
}
})
);
// Get the ID of the last document to use as the next cursor
let nextCursor = null;
if (forumData.length === pageSize) {
nextCursor = forumData[forumData.length - 1].id;
}
return {
data: forumData,
cursor: nextCursor,
};
}