创建侦听器时调用 Firestore“ListenerRegistration”,应该是?

Posted

技术标签:

【中文标题】创建侦听器时调用 Firestore“ListenerRegistration”,应该是?【英文标题】:Firestore "ListenerRegistration" being called when listener is created, should be? 【发布时间】:2021-01-22 17:10:25 【问题描述】:

我正在使用带有 Firebase SDK 的 Unity,使用 Firebase 的 Auth 和 Firestore 实用程序。

我可以从我的客户端对我的 Firestore 数据库进行各种操作,所以现在我正在尝试实现一些客户端挂钩,所以当 Firestore 中的某些内容发生变化时,客户端将执行一个动作。

我构建这些侦听器的方式受到Firebase Documentation 的启发,这是我在发生变化时将侦听器设置为 Firestore 集合的方法示例:

//db == FirebaseFirestore.DefaultInstance;

public ListenerRegistration SetListenerToAllCollectionDocuments(string collectionID, Query query = null, Action OnSomeDocumentChange = null)

    try
    
        Query colRef = query ?? db.Collection(collectionID);

        ListenerRegistration listener = colRef.Listen(colQuerySnapshot =>
        
            Debug.Log("Listen changes on collection:" + collectionID);
            OnSomeDocumentChange();                
        );
        return listener;
    
    catch (Exception e)
    
        Debug.Log(e);
    
    return null;

那我可以这样称呼它:

ListenerRegistration listener = Database.SetListenerToAllCollectionDocuments("users", null, () =>  Debug.Log("Something Change"); );

如果我想禁用监听器参考。

到目前为止一切顺利,现在问题来了: 当数据库中的某些内容发生更改时,此侦听器会被正确调用,但是当我在设置侦听器时第一次调用方法 SetListenerToAllCollectionDocuments(); 时会调用 ALSO

这应该是预期的行为吗?

在我看来,这应该只在 firestore 上的某些内容发生变化时调用,而不是在我创建侦听器时调用。我做错了什么?谢谢。

【问题讨论】:

您在链接上看到了吗:“C# 客户端库中尚不支持” 【参考方案1】:

当您附加集合/查询时,预计会使用集合/查询中的所有现有数据调用侦听器。

如果您只想获取新数据/更新,则需要在您的应用程序代码中确保这一点。常见的方法是在每个文档中添加一个lastUpdated时间戳,然后查询lastUpdated之后的item。

【讨论】:

我会试试的,谢谢@Frank,我认为这是关于本地更改元数据的问题:( 我有一个疑问,如果我只查询 lastUpdated 现在之后的项目,我永远不会被注意到,因为任何其他用户都不可能在未来进行更改。我的意思是,如果我在上午 8 点进行更改,人们也在上午 8 点,所以没有“现在之后”......我必须为每个“lastTimeIchecked”和“lastUpdated”或类似的东西存储一个参考? :S “现在”取决于您的用例。如果您只想查看自上次读取数据库以来的更改,则需要知道上次读取数据库的时间并将其传递到查询中。但是,如果您只想知道应用程序启动后发生的更改,那么您现在就可以查询更改。如果您保留实时侦听器,则在附加侦听器后执行的操作将触发该侦听器。【参考方案2】:

这种检测第一次通话的方法对我有用

    private bool IsSnapshotInitialCall(QuerySnapshot snapshot)
    
        if (snapshot.Documents.Count == 0 && snapshot.Changes.Count == 0) return true;

        if (snapshot.Documents.Count > 1 && snapshot.Changes.Count == snapshot.Documents.Count) return true;

        return false;
    

然后在每个监听器回调的第一行调用它:

    private void MyListenerCallback(QuerySnapshot snapshot)
    
        if (IsSnapshotInitialCall(snapshot)) return;
        // ...
    

【讨论】:

以上是关于创建侦听器时调用 Firestore“ListenerRegistration”,应该是?的主要内容,如果未能解决你的问题,请参考以下文章

JavaWeb中监听器

Servlet监听器汇总

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

locationListener 仅在服务中请求时调用一次

关于几种监听器的区别

Swift/Firestore:完成不会被调用