1

I'm listening to only one added document in a collection, and after it is read I need this document to be deleted. This is the code I implemented:

func createListener(){
    guard let currentUid = Auth.auth().currentUser?.uid else { return }
    listener = db.collection("Collection").document(currentUid).collection("Collection").addSnapshotListener({ listenerSnapshot, error in
        if let error = error{
            print(error.localizedDescription)
            return
        }
        listenerSnapshot?.documentChanges.forEach({ change in
            if change.type == .added{
                let data = change.document.data()
                
                let myview = MYView(data: data)
                guard let window = UIApplication.shared.windows.last else { return }
                myview.present(to: window) {
                    change.document.reference.delete()
                }
            }
        })
    })
}

The problem is that after the document is deleted with

change.document.reference.delete()

The listener snippet change.type == .added is triggered even if the document has been deleted. I don't know why...

How can I only listen for actually ADDED documents in a Firestore Collection?

EDIT:

listening for a specific document but still closure called when document is deleted:

listener = db.collection("Collection").document(currentUid).addSnapshotListener({ listenerSnapshot, error in
        if let error = error{
            print(error.localizedDescription)
            return
        }
        guard let data = listenerSnapshot?.data() else { return }
        let myview = MYView(data: data)
            
        guard let window = UIApplication.shared.windows.last else { return }
        myview.present(to: window) {
            listenerSnapshot?.reference.delete()
        }
    })
StackGU
  • 868
  • 9
  • 22

1 Answers1

1

I'm listening to only one added document in a collection.

No, you're not. You're attaching a snapshot listener to a collection and not to a single document:

db.collection("Collection")
  .document(currentUid)
  .collection("Collection") //
  .addSnapshotListener(/* ... */)

This means that you're listening for real-time updates for each operation that takes place inside the entire sub-collection called "Collection".

What you're basically doing, you're saying, hey Firestore, give me all documents that exist in that sub-collection and keep the listener alive. This listener will be invoked every time a document in that collection changes over time.

If you want to listen to a single document, then you should add a call to .document() and pass a specific document ID:

db.collection("Collection")
  .document(currentUid)
  .collection("Collection")
  .document("someDocumentId") //
  .addSnapshotListener(/* ... */)

In this way, you'll only be notified about the changes to a single document.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • 1
    This makes actual sense, what a mistake, thank you!! – StackGU Oct 04 '22 at 11:14
  • Even if I listen for a specific document the closure is called 2 times: when the document is added and when the document is deleted: I attach the code in the original question's EDIT – StackGU Oct 04 '22 at 11:53
  • That's normal behavior, you [cannot skip the reading of initial data](https://stackoverflow.com/questions/53156109/how-to-skip-initial-data-and-trigger-only-new-updates-in-firestore-firebase). – Alex Mamo Oct 04 '22 at 12:00
  • Isn't there a trick to do it? I'm trying to listen to that specific document for presenting a notification when the user uses the app in the foreground. But since there is this behaviour the notification is received 2 times.... – StackGU Oct 04 '22 at 13:24
  • 1
    Run a [Cloud Function for Firebase](https://firebase.google.com/products/functions) when that particular document is deleted. In this way, you'll only have a single event, and not two. – Alex Mamo Oct 04 '22 at 13:43