Introduction
In order to listen all the docs of my collection that have beed removed, without downloading the entire collection, I am doing the same as commented here.
Rather than deleting docs completely, just add a "deleted: true" property and then listen on the query "db.collection("cities").where("deleted", "==", true)"
Problem
For some reason I don't understand, I am receiving all the "modified" events as "added" from my Firestore listener.
Chat Room Deletions Code
I am implementing a chat list screen with pagination, so I am just fetching old docs when the screen is mounted, and subscribing to all changes that happens on each chat room doc after new Date() (the time in which the screen is mounted).
For "removing" the chat room docs, I am doing the following:
async function deleteChatRoom(chatRoomId, userId) {
const chatRoomRef = firestore.collection("chats").doc(chatRoomId);
const chatRoomDoc = await chatRoomRef.get();
const chatRoomData = chatRoomDoc.data();
const messagesPath = `${chatRoomRef.path}/messages`;
// Check that the user is member of the room
if (!chatRoomData.members[userId]) {
throw chatErrors.notChatRoomMember();
}
// Delete all the chatroom messages
await deleteCollection(messagesPath);
// Delete the chat room
await chatRoomRef.update({
deleted: true, <----
lastMessage: admin.firestore.FieldValue.delete(), // Delete denormalized sensitive data
modifiedAt: admin.firestore.FieldValue.serverTimestamp(), <----
read: admin.firestore.FieldValue.delete(), // Delete denormalized sensitive data
});
}
As you can see, I am updating the "modifiedAt" and "deleted" fields.
Listener Code
With this, what I am trying to reach is being able to listen to all the chat room changes ("lastMessage" field updates, "read" field updates, "deletions"...) that happens after new Date() in the client side, as I commented before. As follows:
export function listenMyChats(
startAt = undefined,
onNext,
onError
) {
const currentUserId = getCurrentUser()?.uid;
if (!currentUserId) {
throw authErrors.authenticationRequired();
}
let query = firestore
.collection("chats")
.where("membersArray", "array-contains", currentUserId)
.orderBy("modifiedAt");
if (startAt) {
query = query.startAt(startAt);
}
return query.onSnapshot(onNext, onError);
}
Something that has sense to me, as I am avoiding reading the entire collection when using the field "startAt" and "orderBy(modifiedAt)".
Subscribing code
Then, to handle all and subscribe to the chat room changes, I am doing the following:
const handleChatsChanges = async (querySnapshot) => {
const changes = querySnapshot.docChanges();
await Promise.all(
changes.map(async (change) => {
if (change.type === "added") {
// NEW INCOMING CHATS
console.log("Added");
} else if (change.type === "modified") {
// MODIFIED CHATS ("deleted", "read", "lastMessage" fields...)
console.log("Modified");
}
});
);
};
useEffect(() => {
const listener = listenMyChats(
startAfter.current,
handleMyChatsChanges,
handleOnListenMyChatsError
);
return () => {
listener();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
The main problem I am experiencing is that, instead of getting the document modifications in the "modified" scope, I am getting "added" events... Why is this happening?
I thought that the listeners behavior were to get all the docs that match the query condition (as "added") when subscribing. And that, after this, the "added" scope was only executed when new docs were added to the target collection (matching the query conditions, of course).
So, why am I receiving the docs fields modifications as "added"?