Can Cloud Firestore onSnapshot() only trigger on changes, and not get the initial state?

后端 未结 4 1553
故里飘歌
故里飘歌 2020-12-17 20:35

The documentation says:

You can listen to a document with the onSnapshot() method. An initial call using the callback you provide creates a document s

相关标签:
4条回答
  • 2020-12-17 21:11

    Firestore listeners loads by their own order and the "onSnapshot" event must always execute first on initial state. But, you can handle that behavior adding a initial state variable like:

    var initState = true;
    db.collection('col').doc('id').onSnapshot(....
    

    Then you could validate inside the function the code you dont want to run when your application starts.

    var initState = true;
    db.collection('col').doc('id').onSnapshot(....
    if(!initState){ // if is not initial state
       //your code
    }
    

    and after the application starts up you must change initState to false and add a sleep/timeout function (cause it may have an unexpcted asyncronous load)

    var initState = true;
    db.collection('col').doc('id').onSnapshot(....
    if(!initState){ // if is not initial state
       //your code
    }
    
    setTimeout(function () { // cause onSnapShot executes first
       initState = false;
    }, 2000);
    
    0 讨论(0)
  • 2020-12-17 21:12

    Firestore listeners don't work that way. You will always be delivered the document(s) relevant to the fetch or query, then updates after that for as long as the listener remains added. There is no mode to receive deltas only.

    If you want to receive only certain data, you might want to figure out how to query for it, for example, by adding a timestamp field and having the client only query for documents that have changed since some prior time.

    0 讨论(0)
  • 2020-12-17 21:14

    What also worked for me was to check for the document.readystate and then choose to act on the snapshot changes. Like this -

    db.collection("collectionName").onSnapshot( (snapshot) => {
        console.log(snapshot.docChanges())
        if( ["loaded","interactive", "complete"].indexOf(document.readyState) >=0 ){
            <-----Your code to act on the snapshot changes---->
    
    }
    
    

    Based on the readystate property documentation here - https://www.w3schools.com/jsref/prop_doc_readystate.asp

    0 讨论(0)
  • 2020-12-17 21:21

    After reading the first and second solution, I have made a solution that seems to work. First you initialize a variable to true and inside the onSnapshot() method you check if this variable is true, if it is, you change it to false, and on else you write your retrieving data algorithm. Something like this:

    var initState = true;
    
    let observer = records.onSnapshot(docSnapshot => {
    
        console.log(`Received doc snapshot`);
    
        if (initState) {
            initState = false;
        } else {
            if (!docSnapshot.docChanges().empty) {     
                docSnapshot.docChanges().forEach(function (change) {
                   //Write here wahtever you want
    
                });
            }
        }
    
    }, err => {
        console.log(`Encountered error: ${err}`);
    });
    
    0 讨论(0)
提交回复
热议问题