I’m building a chat app that and I’d like to listen to doc changes to push new messages as opposed to re-rendering every doc with a change.
Firebase has a solution with the following:
https://firebase.google.com/docs/firestore/query-data/listen#view_changes_between_snapshots
this is also the same solution I found on Stack, but for some reason it’s not working for me.
getMessages(docId: string) {
const msgCollection = collection(getFirestore(getApp()), `matches`, `${docId}`, `messages`);
return query(msgCollection, orderBy('createdAt', 'asc'));
}
getMessages(matchId: string) {
const q = this.chatSvc.getMessages(matchId);
onSnapshot(q, (QuerySnapshot: any) => {
QuerySnapshot.docChanges().forEach((doc) => {
this.messages.push({ ...doc.data(), id: doc.id });
});
console.log('mess', this.messages)
});
}
It was working before i added docChanges(), but once i added it I’m getting this console error:
zone.js:218 Uncaught TypeError: doc.data is not a function
at chat.page.ts:61:39
at Array.forEach (<anonymous>)
at chat.page.ts:60:36
at angular-fire.js:207:29
at angular-fire.js:163:45
at _ZoneDelegate.invoke (zone.js:409:30)
at Object.onInvoke (core.mjs:26518:33)
at _ZoneDelegate.invoke (zone.js:408:56)
at Zone.run (zone.js:169:47)
at NgZone.run (core.mjs:26372:28)
As far as I can see, my code matches the example in the firebase doc with the exception of:
if (change.type === "added")
The plan is to add the conditional statement once I get docChanges() working.
>Solution :
The docChanges() method returns the following Array<DocumentChange <T>>. Therefore in your code the variable doc will be of type DocumentChange. Then inside DocumentChange you have a property called doc of type QueryDocumentSnapshot which would have the method data(). Therefore in your code you have to do:
this.messages.push({ ...doc.doc.data(), id: doc.doc.id });