-
Notifications
You must be signed in to change notification settings - Fork 990
Description
Operating System
Mac OS Ventura 13.5.2
Browser Version
Google Chrome Version 117.0.5938.132
Firebase SDK Version
10.4.0
Firebase SDK Product:
Firestore
Describe your project's tooling
React app using Vite's react template, React version 18.2.0, Firebase web version 9 sdk version 10.4.0
Describe the problem
getDocs() currently hangs when trying to paginate data in firestore using the following query cursors startAfter, endAt, limit, and limitToLast. I am noticing the getDocs() queries will randomly hang and the promises never get resolved. The lastDoc and firstDoc references are always correct when running the queries, it just seems the getDocs() promises hang and never resolve at random. I am currently experiencing this heavily using emulators, but I can only assume this affects production as well.
Steps and code to reproduce issue
Set up a react app template using vite. The below code examples are being used to query a collection in firebase.
Initial fetch always works
useEffect(() => {
console.log('this is running')
const fetchData = async () => {
let q = query(
collection(db, 'appointments.requests'),
orderBy('created'),
limit(rowsPerPage + 1)
)
const querySnapshot = await getDocs(q)
const initialData = querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data()
}))
setFirstVisibleDoc(querySnapshot.docs[0])
if (querySnapshot.docs.length <= rowsPerPage) {
setHasMore(false)
setLastVisibleDoc(querySnapshot.docs[querySnapshot.docs.length - 1])
} else {
setHasMore(true)
setLastVisibleDoc(querySnapshot.docs[querySnapshot.docs.length - 2])
}
setRows(initialData.slice(0, rowsPerPage))
setLoading(false)
}
fetchData()
}, [rowsPerPage])
Querying next page and previous page will randomly hang at the line where getDocs(q) is being called as I go to nextPage or previousPage.
const getNextPage = async () => {
const q = query(
collection(db, 'appointments.requests'),
orderBy('created'),
startAfter(lastVisibleDoc),
limit(rowsPerPage + 1)
)
console.log(q)
console.log(lastVisibleDoc)
let querySnapshot
try {
console.log('in try catch next')
querySnapshot = await getDocs(q)
} catch (error) {
console.log('error next', error)
}
console.log('getNextSnapshot', querySnapshot)
const allData = querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data()
}))
setFirstVisibleDoc(querySnapshot.docs[0])
if (allData.length <= rowsPerPage) {
setHasMore(false)
setLastVisibleDoc(querySnapshot.docs[querySnapshot.docs.length - 1])
} else {
setHasMore(true)
setLastVisibleDoc(querySnapshot.docs[querySnapshot.docs.length - 2])
}
setRows(allData.slice(0, rowsPerPage))
setPage((prevState) => prevState + 1)
}
const getPreviousPage = async () => {
const q = query(
collection(db, 'appointments.requests'),
orderBy('created'),
endAt(firstVisibleDoc),
limitToLast(rowsPerPage + 1)
)
console.log(q)
console.log(firstVisibleDoc)
let querySnapshot
try {
console.log('in try catch prev')
querySnapshot = await getDocs(q)
} catch (error) {
console.log('error prev', error)
}
console.log('getPreviousSnapshot', querySnapshot)
const allData = querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data()
}))
setFirstVisibleDoc(querySnapshot.docs[0])
setLastVisibleDoc(querySnapshot.docs[querySnapshot.docs.length - 2])
setRows(allData.slice(0, rowsPerPage))
setPage((prevState) => prevState - 1)
setHasMore(true)
}
Very hard to diagnose as the try catches do absolutely nothing in terms of error handling.