I am a little lost on how to create infinite scroll elements in next.js with firebase firestore.
I am trying to use "my api" and use firestore on my api files.
My call to api is like this for now. I have a list called data, I send a request to my api and get the first 9 (limit param) docs.
useEffect(() => {
console.log("useEffect");
const getImage = async () => {
const req = await fetch(`api/firebase?limit=9`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const data = await req.json();
return data;
};
getImage().then((data) => {
setData(data);
});
}, []);
And my request handling is like this:
if (req.method === "GET") {
const qu = req.query;
const max = qu.limit;
const q = query(collection(db, "images"), limit(max));
const querySnapshot = await getDocs(q);
const data = querySnapshot.docs.map((doc) => {
return {
label: doc.data().label,
url: doc.data().url,
id: doc.id,
};
});
res.status(200).json(data);
}
I have tried/ looked up to react-infinite-scroll-component and I think I can make it work but I am lost on how to get the next 9 docs with my api from firebase.
On firestore there's startAfter()
which takes documentSnapshot not an id but I can work with that by saving the id from the last doc send and calling it with getDoc with that id and start after that, but I don't know how to implement that thought with my api calling. Let's say there are 27 docs on my firestore, I call that first 9 with useEffect, do I need another function to call and update my data? I could try sending the last id as param and update but that gets complicated and I don't know if there's a simple way to this.
If anyone else stumble upon such problem here's how i solved it
I added this if statement to my api handler which checks if i sent docID param via call and gets the document with that id, after that i sent that document to startAfter.
if (qu.docID) {
const id = qu.docID;
const max = qu.limit;
const idquery = query(
collection(db, "images"),
where("__name__", "==", id)
);
const documentSnapshots = await getDocs(idquery);
const lastVisible =
documentSnapshots.docs[documentSnapshots.docs.length - 1];
const next = query(
collection(db, "images"),
orderBy("createdAt", "desc"),
startAfter(lastVisible),
limit(max)
);
const querySnapshot = await getDocs(next);
const data = querySnapshot.docs.map((doc) => {
return {
label: doc.data().label,
url: doc.data().url,
id: doc.id,
};
});
res.status(200).json(data);
}
Like Jose German said i created another function for loading more
const getNext = async (docID) => {
console.log("getNext");
const req = await fetch(`api/firebase?limit=9&docID=${docID}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const data = await req.json();
return data;
};
Lasly i used react-infinite-scroll-component's next={} to call my second function and after few tweaks it worked