johnoula
johnoula

Reputation: 31

Firestore onSnaphot returning duplicate data

When I listen to data changes from Firestore I get previous changes together with new ones in an array .How can I retrieve just the new changes without the duplicates? The code below is inside a useEffect()

     await db.collection("Recent").where("members", "array-contains", currentUser.uid)
        .onSnapshot(snapshot => {
            setChatList([])
            setChatList(snapshot.docs.map(doc => doc.data()))
        })

Upvotes: 0

Views: 801

Answers (1)

DIGI Byte
DIGI Byte

Reputation: 4164

This is intended behaviour if you are using set or update on the database as the onSnapshot reacts to cache writes as well as Sync operations.

before any changes are Sync'd, it is in a pending state:

A change event is immediately fired with the new data. The document has not yet been written to the backend so the "pending writes" flag is true. The document is written to the backend. The backend notifies the client of the successful write. There is no change to the document data, but there is a metadata change because the "pending writes" flag is now false.

Additionally:

The snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified). because you are calling the query condition without any filters, onSnapshot is a listener that will return removed data as well as new. you must filter the documents within your list or manage the listener *outside of the useEffect.

As such, I highly suggest modifying your onSnapshot to be outside of the useEffect and in a dedicated function that can react appropriately or use get() as an alternative.

Otherwise, the example provided is suitable for validating the change meta

db.collection("cities").where("state", "==", "CA")
    .onSnapshot((snapshot) => {
        snapshot.docChanges().forEach((change) => {
            if (change.type === "added") {
                console.log("New city: ", change.doc.data());
            }
            if (change.type === "modified") {
                console.log("Modified city: ", change.doc.data());
            }
            if (change.type === "removed") {
                console.log("Removed city: ", change.doc.data());
            }
        });
    });

Source: https://firebase.google.com/docs/firestore/query-data/listen

Upvotes: 2

Related Questions