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

Firebase Cloud Firestore onSnapshot()是否只能在更改时触发,而不能获取初始状态?,firebase,google-cloud-firestore,Firebase,Google Cloud Firestore,报告说: 可以使用onSnapshot()方法侦听文档。使用您提供的回调函数进行的初始调用会立即使用单个文档的当前内容创建文档快照。然后,每次内容更改时,另一个调用都会更新文档快照 我只想让我的侦听器在数据更改时启动。我不希望它在应用程序加载时启动,以获取数据的初始状态。有什么建议吗?Firestore的侦听器不是这样工作的。您将始终收到与获取或查询相关的文档,然后在该文档之后更新,只要侦听器保持添加状态。没有仅接收增量的模式 如果您只想接收某些数据,您可能想知道如何查询这些数据,例如,添加一个

报告说:

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


我只想让我的侦听器在数据更改时启动。我不希望它在应用程序加载时启动,以获取数据的初始状态。有什么建议吗?

Firestore的侦听器不是这样工作的。您将始终收到与获取或查询相关的文档,然后在该文档之后更新,只要侦听器保持添加状态。没有仅接收增量的模式


如果您只想接收某些数据,您可能想知道如何查询这些数据,例如,添加一个时间戳字段,让客户端仅查询自以前某个时间以来已更改的文档。

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,并添加一个sleep/timeout函数(因为它可能有一个未完成的异步负载)


在阅读了第一个和第二个解决方案后,我提出了一个似乎有效的解决方案。 首先将变量初始化为
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}`);
});

对我来说,检查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---->

}

db.collection(“collectionName”).onSnapshot((快照)=>{
console.log(snapshot.docChanges())
if([“已加载”、“交互式”、“完成”].indexOf(document.readyState)>=0){
}
基于此处的readystate属性文档-

如果能够忽略初始状态,那就太好了。在我的应用程序中,我正在与Firebase同步数据,并将其存储在CoreData中,以供我的应用程序进一步使用。在应用程序启动时,我从侦听器获取所有数据,甚至是我已经存储的数据,这让人非常恼火。我现在需要找到一种方法来忽略第一个状态我们是否保证所有本地数据(初始状态)都会有1个响应其中不会包含来自服务器的任何新信息?如果是,我可以忽略侦听器的一个响应以实现我想要的功能。你不能忽略数据。你可以构建一个只返回你想要的数据的查询。如果你不能构建这样的查询,那么你就走运了。获得Etag会很好在阅读的同时,下次你阅读同一个集合时,你可以提供你的Etag作为“这是我已经拥有的”,如果Firestore中有更新的Etag,它在下一个查询中只发送增量。多谢你在这方面的官方支持,道格先生。我对你的声明“Firestore侦听器不是那样工作的”有疑问…文档指出,此隐式行为是为了方便使用初始状态填充UI而设计的。在这种情况下,应该为用户提供是否接收初始状态的选项,对吗?一个字段,例如
ListenerOptions.getInitialState()
ListenerOptions.ignoreInitialState()
将使
onSnapshot()
方法更加灵活,就像“SetOptions.merge()“!这是合理的要求吗,Firebaser?”D@varun当然,您可以随时向Firebase支持提交功能请求。我喜欢此功能!注意:此解决方案非常肤浅,它所做的只是忽略使用(if…else)的第一次数据提取OP问题的唯一解决方案是等待firestore团队给我们一个API,使初始快照成为可选的。
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---->

}