Typescript React + Firestore嵌套注释优化



我大学团队项目的一部分包括一个博客系统。我用firebase实现了一个嵌套注释系统。我的代码的问题是,在对评论或帖子进行任何更改之后,无论是编辑,删除还是添加,它都会再次从顶部查询数据库。招致我已经读过的所有内容。我怎样才能只查询缺少的评论?把它附加到当前的注释对象上?

Firestore结构:文章/{userId}/文章/{postID}/评论/{commentId}

评论数据:评论数据

let lastDocument: DocumentData | undefined | null;
let commentLimit = 3;
let comments: object[] = [];
const history = useHistory();
let { uid, slug } = useParams<{ uid: string, slug: string }>();
const [post, setPost] = useState<any>(SINGLE);
const [imageURL, setImageURL] = useState("");
const postDocRef = doc(db, "posts", `${uid}/posts/${slug}`);
const commentCollectionRef = collection(postDocRef, "comments");

查询:

useEffect(() => {
onSnapshot(postDocRef, async (result) => {
lastDocument = null;
if (result.exists()) {
setImageURL(result.get("image").downloadURL);
setPost({
id: result.id,
desc: result.get("appendix"),
userId: result.get("userId"),
postType: "standard",
readingTime: calculateReadingTime(result.get("content")),
href: `/single/${uid}/${slug}`,
date: result.get("createdAt").toDate().toDateString(),
featuredImage: result.get("image").downloadURL,
like:
{
count: result.get("heartCount"),
isLiked: await checkPostLiked(result.get("docID")),
},
bookmark: {count: 3502, isBookmarked: false},
tags: result.get("tags"),
comments: await getAllComments(),
...result.data()
})
} else history.push("/page404");
})}, [uid, slug]);

嵌套评论:

const nest = (items: any, id: number | null | undefined): any => {
return items.filter((item: any) => item.parentId === id).map((item: any) => ({
...item,
children: nest(items, item.id as number | null),
}));
};

查询评论:

const getNestedComments = async (rootComment: any) => {
const document = await getDoc(doc(commentCollectionRef, rootComment));
if (document.get("childrens")){
for (let childComment of document.get("childrens")){
comments.push(await getNestedComments(childComment));
}
}
return {
docId: document.id,
date: document.get("createdAt").toDate().toDateString(),
...document.data()
};
};

const getAllComments = async () => {
comments = [];
const q = (lastDocument) ?
query(commentCollectionRef,
where("parentId", "==", null),
orderBy("createdAt", "desc"),
startAfter(lastDocument),
limit(commentLimit))
:
query(commentCollectionRef,
where("parentId", "==", null),
orderBy("createdAt", "desc"),
limit(commentLimit))
const snapshot = await getDocs(q);
for (let commentDoc of snapshot.docs){
if (commentDoc.get("childrens")){
for (let comment of commentDoc.get("childrens")){
comments.push(await getNestedComments(comment));
}
}
comments.push({
docId: commentDoc.id,
date: commentDoc.get("createdAt").toDate().toDateString(),
...commentDoc.data()
})
}
lastDocument = snapshot.docs[snapshot.docs.length - 1];
return nest(comments, null);
}

// Get More comments
const handleMoreComments = async () => {
comments = [];
setPost({
...post,
comments: [...post.comments.concat(await getAllComments())]
})
}

以上方法确实有效。然而,从扩展的角度来看,这是一个糟糕的解决方案。任何帮助都是感激的。由于

在对评论或帖子进行任何更改后,[它会引起]我已经拥有的所有读取

如果您在SDK中启用本地持久性,那么任何未修改的文档都将从缓存中读取,而不必从服务器重新读取。

您仍然可以处理snapshot.docs,但是未修改的文档将来自本地缓存。或者,您可以处理snapshot.docChanges,只处理在前一个快照和这个快照之间更改的文档。

最新更新