【问题标题】:How do you unsubscribe Firebase ChildAdded events in Unity C#?如何在 Unity C# 中取消订阅 Firebase ChildAdded 事件?
【发布时间】:2020-07-28 06:40:19
【问题描述】:

我有多个帖子,每个帖子都有自己的 cmets。因此,当我打开帖子的评论列表时,我想开始监听ChildAdded 事件以加载 cmets。 我有

public void StartListening(string postKey) {  
  databaseReference
    .Child(FirebaseConstants.DatabasePosts)
    .Child(postKey)
    .Child(nameof(PostInfo.Comments))
    .ChildAdded += OnCommentChildAdded;
}

这将获取所有当前的 cmets,然后如果有任何实时的 cmets(包括当前用户),它也会显示在列表中。

当我关闭该帖子并转到另一个帖子时,我想停止收听旧帖子上的 cmets 并开始收听另一个帖子。所以我有

databaseReference 
 .Child(FirebaseConstants.DatabasePosts) 
 .Child(postKey)
 .Child(nameof(PostInfo.Comments))
 .ChildAdded -= OnCommentChildAdded;

停止收听原来的 postKey,然后我用新的 postKey 再次调用第一个函数。

我的问题是,当我返回原始帖子并调用 StartListening(originalPostKey); 时,它会很好地加载所有现有的孩子,但是当我实时添加评论时,它会触发 OnCommentChildAdded 两次,就像第一次订阅一样活动从未取消订阅。

有谁知道 Unity C# 中的 Firebase 子事件是如何工作的,以及如何在没有 hack 的情况下让它工作(例如检查一个集合以查看是否已添加 postKey)。 p>

【问题讨论】:

    标签: c# firebase unity3d firebase-realtime-database


    【解决方案1】:

    如果不查看实际执行 sn-ps 的位置、方式和时间的代码,这有点难以判断。

    但是,一般来说,在使用+= 之前,请始终尝试使用-=。如果侦听器从未被附加,这也是有效的,但应确保它只被添加恰好一次,即使StartListening 被多次调用。

    public void StartListening(string postKey) 
    {  
        var child = databaseReference.Child(FirebaseConstants.DatabasePosts).Child(postKey).Child(nameof(PostInfo.Comments));
    
        child.ChildAdded -= OnCommentChildAdded; 
        child.ChildAdded += OnCommentChildAdded; 
    }
    

    【讨论】:

      【解决方案2】:

      我相信您遇到的问题是因为您删除了错误帖子上的听众。如果您的代码看起来像这个块,您删除新帖子上的侦听器,而不是旧帖子。但是,这并不能解释为什么会添加两次侦听器。

      StartListening(string postKey) {  
        databaseReference.Child(FirebaseConstants.DatabasePosts).Child(postKey).Child(nameof(PostInfo.Comments)).ChildAdded -= OnCommentChildAdded;
        databaseReference.Child(FirebaseConstants.DatabasePosts).Child(postKey).Child(nameof(PostInfo.Comments)).ChildAdded += OnCommentChildAdded;
      }
      

      为了解决这个问题,您必须存储您之前收听的帖子的密钥(或引用)。

      private string mActivePostKey = null;
      
      public void ListenTo(string postKey) 
      {
          // Ignore relistening to the same post (optional)
          if (String.Equals(postKey, mActivePostKey)) return;
          
          // Clear the previous listener, if attached
          if (activePostKey != null) {
            Debug.Log("Detaching listener to " + mActivePostKey);
            var activeChildRef = databaseReference.Child(FirebaseConstants.DatabasePosts).Child(mActivePostKey).Child(nameof(PostInfo.Comments));
            activeChildRef -= OnCommentChildAdded;
          }
          
          // Add listener
          Debug.Log("Attaching listener to " + postKey);
          var childRef = databaseReference.Child(FirebaseConstants.DatabasePosts).Child(postKey).Child(nameof(PostInfo.Comments));
          childRef.ChildAdded += OnCommentChildAdded; 
          
          // Replace active post key
          mActivePostKey = postKey;
      }
      

      如果上述代码正常运行,代码

      someObject.ListenTo("POST_ID_1")
      someObject.ListenTo("POST_ID_2")
      someObject.ListenTo("POST_ID_1")
      

      应该输出:

      Attaching listener to POST_ID_1
      Detaching listener to POST_ID_1
      Attaching listener to POST_ID_2
      Detaching listener to POST_ID_2
      Attaching listener to POST_ID_1
      

      如果包含此方法的对象/类与原始实例不同,则使用-= OnCommentChildAdded; 将不起作用,因为这些方法将具有不同的地址(即Instance1#OnCommentChildAdded != Instance2#OnCommentChildAdded)。它还会导致以下消息:

      Attaching listener to POST_ID_1
      Attaching listener to POST_ID_2
      Attaching listener to POST_ID_1
      

      【讨论】:

        猜你喜欢
        • 2017-04-25
        • 2017-12-06
        • 1970-01-01
        • 1970-01-01
        • 2021-03-29
        • 2017-07-16
        • 2020-01-01
        • 2017-02-12
        • 2013-04-15
        相关资源
        最近更新 更多