Cloud Firestore onSnapshot()只能在更改时触发,而不能获取初始状态吗?

时间:2018-10-23 18:17:22

标签: firebase google-cloud-firestore

documentation说:

  

您可以使用onSnapshot()方法收听文档。使用您提供的回调进行的初始调用会立即使用单个文档的当前内容创建一个文档快照。然后,每次内容更改时,另一个调用都会更新文档快照。

我只希望数据更改时触发我的监听器。我不希望它在应用加载时触发,以获取数据的初始状态。有什么建议吗?

4 个答案:

答案 0 :(得分:3)

Firestore侦听器不能那样工作。您将始终收到与获取或查询相关的文档,然后在此之后进行更新,只要保持添加了侦听器即可。没有仅接收增量的模式。

如果您只想接收某些数据,则可能想弄清楚如何查询数据,例如,添加一个时间戳字段,并使客户端仅查询自前一段时间以来发生过更改的文档。

答案 1 :(得分:2)

在阅读第一个和第二个解决方案之后,我提出了一个似乎可行的解决方案。 首先,您将变量初始化为true,并在onSnapshot()方法内检查此变量是否为true,如果是,则将其更改为false,否则,将其更改为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}`); }); 。编写您的检索数据算法。像这样:

if (!requireNamespace("BiocManager", quietly = TRUE))
  install.packages("BiocManager")
BiocManager::install(version='3.10')

BiocManager::install("DAPAR")
BiocManager::install("Prostar")


library(Prostar)
Prostar()

答案 2 :(得分:0)

对我也有用的是检查document.readystate,然后选择对快照更改进行操作。像这样-

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---->

}

基于此处的readystate属性文档- https://www.w3schools.com/jsref/prop_doc_readystate.asp

答案 3 :(得分:-1)

Firestore侦听器按其自己的顺序加载,并且“ onSnapshot”事件必须始终在初始状态下首先执行。但是,您可以通过添加初始状态变量来处理该行为,例如:

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

然后,您可以在函数中验证您不想在应用程序启动时运行的代码。

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

在应用程序启动后,您必须将initState更改为 false 并添加一个睡眠/超时功能(因为它可能具有意外的异步负载)

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);