区分 Firestore 中的第一次查询快照和更改侦听器

Posted

技术标签:

【中文标题】区分 Firestore 中的第一次查询快照和更改侦听器【英文标题】:Differentate between first time querysnapshot and change listener in firestore 【发布时间】:2018-09-22 17:35:42 【问题描述】:

我正在关注 firestore here 的文档,并尝试在集合上附加快照侦听器以获取实时更新。

我在尝试区分来自 Snapshot 事件侦听器的响应是第一次响应(在这种情况下将返回集合中的所有文档)还是更改事件响应时遇到了麻烦,在这种情况下我想要添加检查以确定发生了什么变化。 这 同一文档中的脚注:

重要提示:第​​一个查询快照包含与查询匹配的所有现有文档的添加事件。这是因为您正在获得一组更改,这些更改使您的查询快照与查询的初始状态保持同步

没有提到如何识别第一个查询快照和后续查询快照。

我可以在 SO 上找到的唯一相关问题是 one,但在我的情况下它无济于事。

非常感谢任何帮助,因为我已经找不到要去的地方了。

谢谢。

【问题讨论】:

据我了解,每次打开活动时,它都会读取所有文件,对吗?之后只计算修改和删除的文档? 【参考方案1】:

// flag
let flag = false;

collectionRef.onSnapshot((snapshot) => 
snapshot.docChanges().forEach((change) => 

    // NOTE: ctrl first execute
    if (!flag) 
        console.log('not initilized');
        return;
    

    // anything
    console.log('only after initilized');
, (err) => 
    console.log(err);
);

// set flag true 
if (!flag) 
    flag = true
    console.log('listener initilized!!');
;
);

【讨论】:

这对应于所有通知,除非是第一次设置监听器。甚至可以获取文档的第一次添加通知。 虽然您所写的内容可能会回答这个问题,但在explanation 中似乎确实缺少一些内容,并且可能会给其他用户造成非法混淆。您能否扩展您的答案,使其更清晰、更易于理解?这将提供更好的答案,并帮助未来的用户了解问题是如何解决的。【参考方案2】:

仔细查看您引用的文档中的代码。它正在检查 QuerySnapshot 对象中每个 DocumentChange 对象的 Type:

for (DocumentChange dc : snapshots.getDocumentChanges()) 
    switch (dc.getType()) 
        case ADDED:
            Log.d(TAG, "New city: " + dc.getDocument().getData());
            break;
        case MODIFIED:
            Log.d(TAG, "Modified city: " + dc.getDocument().getData());
            break;
        case REMOVED:
            Log.d(TAG, "Removed city: " + dc.getDocument().getData());
            break;
    

这与您引用的文本一致:

第一个查询快照包含与查询匹配的所有现有文档的添加事件。

您可以判断您是否第一次看到文档,因为它是一种添加类型的更改。 MODIFIED 和 REMOVED 类型更改仅针对您之前看到的此侦听器的文档发出。

【讨论】:

谢谢道格。如果我知道这是第一个查询快照并传递整个列表,我希望跳过这个 switch-case 检查,我可以使用它来填充 UI。对于随后对事件侦听器的调用,我计划使用检查并考虑文档更改类型等。这是否可能? 你当然可以在监听器中维护你自己的状态,它知道它是否是第一次被调用。 也许看看这个? medium.com/@stle/… @OmomSun 你能帮我在 android 上使用相同的代码吗,我在过去 3 天陷入同样的​​情况。 我们如何区分第一个 ADDED 和监听时添加的文档?

以上是关于区分 Firestore 中的第一次查询快照和更改侦听器的主要内容,如果未能解决你的问题,请参考以下文章

Flutter StreamBuilder中使用的Firestore快照在数据更改时永远不会更新

Firebase Firestore get() 快照在第二次查询时冻结

Firestore 单文档快照流未更新

Firestore 查询返回未定义快照的位置(Vue.js / Firestore / Vuefire)

Swift 快照和映射来自 Firestore 的单个文档

Firestore:如果两个侦听器监听相同的查询 firebase 维护两个不同的查询快照?