【问题标题】:Firestore "ListenerRegistration" being called when listener is created, should be?创建侦听器时调用 Firestore“ListenerRegistration”,应该是?
【发布时间】: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# 客户端库中尚不支持”

标签: c# firebase unity3d google-cloud-firestore listener


【解决方案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;
        // ...
    }

【讨论】:

    猜你喜欢
    • 2021-01-06
    • 2019-06-29
    • 1970-01-01
    • 2021-07-12
    • 2020-11-09
    • 2023-03-19
    • 1970-01-01
    • 2013-02-02
    相关资源
    最近更新 更多