I'm creating a comment system for a social media project using react and firestore. I've successfully implemented the pagination functionality; the only issue I'm having now is that I want to hide the "load more comments" button when the data retrieved from the database is less than the limit, and show it when the data in the database exceeds the limit. I looked through the documentation, but it appears that Firebase does not support "checking or looking ahead for additional documents that are not within the limit." Please Is there any way to solve this problem?
Below is what I have got so far
const [comments, setComments] = useState([])
const [lastVisible, setLastVisible] = useState(null)
const [hasMorePages, setHasMorePages] = useState(false)
const pageSize = 3
let q = query(
collection(db, `/posts/${post.post_id}/comments`),
orderBy('createdAt', 'desc'),
limit(pageSize)
)
useEffect(() => {
const getSnapshot = onSnapshot(q, (querySnapShot) => {
const cmt = []
querySnapShot.forEach((dat) => {
cmt.push({ ...dat.data(), comment_id: dat.id })
})
setLastVisible(querySnapShot.docs[querySnapShot.docs.length - 1])
setComments(cmt)
setHasMorePages(true)
})
return () => getSnapshot()
}, [])
const pageSize_paginated = 4
const paginatedFunc = () => {
const next = query(
collection(db, `/posts/${post.post_id}/comments`),
orderBy('createdAt', 'desc'),
startAfter(lastVisible?.data()?.createdAt || 0),
limit(pageSize_paginated)
)
setCommentLoad(true)
const getSnapshot = onSnapshot(
next,
{ includeMetadataChanges: false },
(docSnap) => {
let cmt = []
if (!docSnap.empty) {
docSnap.forEach((snap) => {
cmt.push({ ...snap.data(), comment_id: snap.id })
})
setComments([...comments, ...cmt])
if (docSnap?.docs[docSnap.docs.length - 1]) {
setLastVisible(docSnap.docs[docSnap.docs.length - 1])
}
if (docSnap.docs.length < pageSize_paginated) setHasMorePages(false)
}
}
)
setCommentLoad(false)
return () => getSnapshot()
}
the JSX
{hasMorePages && (
<button className={styles.comment__load} onClick={paginatedFunc}>
load more comments{' '}
{commentLoad && <FontAwesomeIcon icon={faSpinner} />}
</button>
)}
</div>
CodePudding user response:
Nowadays there are two options that pop to mind:
- Use the new COUNT() operator to get the count of all documents, and use that to determine the total number of documents.
- Always retrieve one more document than you display, and use the presence of that extra document to determine whether you show a "Show more" button in the UI.