简体   繁体   中英

snapshot.docChanges() not working in Firebase Firestore

We're having issues with a listener firing at the wrong times. I tried to see the metadata changes with:

firebase.firestore().collection('Users').doc($scope.user.uid).collection($scope.longLanguage).doc('Missing_Word').onSnapshot(function(snapshot) {
        snapshot.docChanges().forEach(function(change) {
          console.log(change.doc.data());
        })

Here's the error message:

Uncaught TypeError: snapshot.docChanges is not a function

I also tried switching on metadataChanges:

firebase.firestore().collection('Users').doc($scope.user.uid).collection($scope.longLanguage).doc('Missing_Word').onSnapshot({includeMetadataChanges: true}, function(snapshot) {
    snapshot.docChanges().forEach(function(change) {
      console.log(change.doc.data());
    })

We wrote this close to the documentation . Any idea what we're doing wrong?

onSnapshot() accepts a callback function that receives a DocumenSnapshot object. DocumentSnapshot doesn't have a docChanges method.

It looks like you were expecting the callback to contain a QuerySnapshot instead, which does have docChanges . You get a QuerySnapshot when you perform a query against a collection, not a single document as you're showing here.

The following examples are in the docs here https://firebase.google.com/docs/firestore/query-data/listen#view_changes_between_snapshots

In browser:

db.collection("cities").where("state", "==", "CA")
    .onSnapshot(function(snapshot) {
        snapshot.docChanges().forEach(function(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());
            }
        });
    });

In nodejs

let observer = db.collection('cities').where('state', '==', 'CA')
  .onSnapshot(querySnapshot => {
    querySnapshot.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());
      }
    });
  });

So please note that both .onSnapshots are on the Firestore.CollectionReference , not on DocumentReference (after doc() )

I had the same problem, docChanges works when use like a function, I fixed the problem using a $.each from jQuery. Follow the code:

blabla...(function(snapshot) {
        $.each(snapshot.docChanges(), function() {
            var change = this
            if (change.type === "added") {
                console.log(change.doc.data()); 
               //show data when is added, apply here your function of callback;
            }
            if (change.type === "modified") {
                console.log(change.doc.data());
                //show data when is modified, apply here your function of callback;
            }
            if (change.type === "removed") {
                //when is removed, apply here your function of callback;
            }
        });
    });

Something else to watch out for: this seems to depend on what version of the Firebase JS SDK you are using. Of course, please make sure to check whether you are calling onSnapshot on a document or a collection, as other answers have pointed out. But in regard to calling it on a collection, I was recently using 4.13.1 and docChanges was not a function, but when I upgraded to v.7.15 I had to change all my snapshot.docChanges to snapshot.docChanges() .

The release notes confirm as much as well. In v.5.0 they changed docChanges into a function. See here for example, from the branch with the 4.13.1 tag, where docChanges is not a function.

If someone has this error message and is looking for an easy to understand answer:

Queries to collections return to you a list of documents. In this case you loop through the list with docChanges().forEach(change => {

db.collection("cities").onSnapshot(querySnapshot => { //onSnapshot on collection
   querySnapshot.docChanges().forEach(change => {
     //do whatever you want here...
   });
});

Queries to a document return to you a single document. In this case, you do not need docChanges() because the snapshot of a single document does not have a function "docChanges"

db.collection("cities").doc("someId") //onSnapshot on a document
.onSnapshot((doc) => {
    console.log("Current data: ", doc.data());
});

This is a simple way of using docChanges() method:

        db.collection("cities").onSnapshot(querySnapshot => {

            let changes = querySnapshot.docChanges();
            for (let change of changes) {
                var data = change.doc.data();
                console.log(data);
            }


        });

docChanges()删除括号,它只是docChanges

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM