Firebase .childAdded 和活动指示器

Posted

技术标签:

【中文标题】Firebase .childAdded 和活动指示器【英文标题】:Firebase .childAdded and activity Indicator 【发布时间】:2017-09-02 18:38:47 【问题描述】:

当我在 API 调用之前启动活动指示器并在之后停止时遇到问题,但是如果我使用 .childAdded 填充 TableView,我将无法正确执行此操作。由于 .childAdded 仅在添加孩子时调用,所以我的活动指示器总是在加载。例如:

func parseData() 
    
    self.activityIndicator.startAnimating()
    
    DataService.instance.SOME_DATA.observe(.childAdded, with:  (snapshot) in
    
        if let snapshot = snapshot.value as? Dictionary<String, Any> 
            let data = someData(data: snapshot)
            self.array.append(data)
        
        DispatchQueue.main.async 
            self.tableView.reloadData()
            self.activityIndicator.stopAnimating()
        
    )

所以基本上如果没有任何值 .childAdded 将不会被调用并且活动指示器将永远不会停止,因为它仅在重新加载 tableView 时才会停止。 有人可以建议如何正确地做到这一点吗?非常感谢。

基于建议答案的一些更新

我将举一个基于聊天应用程序的示例,它会更容易理解。 我有以下数据库结构:

user_messages
   unique_user_id
      unique_user_chat_id
          unique_message_1
          unique_message_2
          unique_message_3
          unique_message_4
messages
   unique_message_1
          text...
   unique_message_2
          text...
   unique_message_3
          text...
   unique_message_4
          text...

我有 2 个视图控制器,每个控制器都有一个 TableView

父视图控制器获取所有 unique_user_chat_id 并且当客户端按下所选聊天时,第二个视图控制器从“消息”对象填充所有子对象。所以基本上第二个 View Controller 不需要调用函数 .observeSingleEvent(of: .value 来获取 unique_user_chat_id,只有 Childs .childAdded in 'messages' object.

【问题讨论】:

【参考方案1】:

正如您所观察到的 childAdded,正如您所说,这可能永远不会被调用。

childAdded 更改为valueChanged 并观察childAdded。将动画调用添加到valueChanged

您不应该在观察 childAdded 时设置活动指示器,仅在获取初始数据时。

func fetchData() 

    activityIndicator.startAnimating()

    DataService.instance.SOME_DATA.observe(.value, with:  (snapshot) in

        // Handle current value and stop activity indicator 
         if let snapshot = snapshot.value as? Dictionary<String, Any> 
              let data = someData(data: snapshot)
              self.array.append(data)
        

        DispatchQueue.main.async 
           self.tableView.reloadData()
           self.activityIndicator.stopAnimating()

           // Observe new childs added
           self.observeData()
       
    )
 

func observeData() 

    DataService.instance.SOME_DATA.observe(.childAdded, with:  (snapshot) in

        if let snapshot = snapshot.value as? Dictionary<String, Any> 
            let data = someData(data: snapshot)
            self.array.append(data)
        

        DispatchQueue.main.async 
            self.tableView.reloadData()
        
    )


【讨论】:

是的,我可以做到这一点,乍一看它会起作用,但是如果用户遇到互联网连接问题?动画将启动,API 不会被调用,动画将在 2 秒后停止(以延迟为例)。 @Sargot 我修改了我的答案。 非常感谢您的帮助!您能否根据您的回答检查我更新的问题并告知我是否正确?另外我不确定我应该调用哪个动画? 但是如果我不需要获取父级呢?我的意思是我只用孩子填充 tableView,比如聊天。我的父母在 tableView 中,我从那里转到详细信息视图并在那里填充我的孩子。 @Sargot 我不明白你想要达到什么目的?观察childAdded 时不要使用活动指示器,这不能保证调用。如果要获取消息列表,请使用.observeSingleEvent(of: .value,,这样可以保证获取一次,之后可以观察到新消息。观察单个值时使用活动指示器。至于您对父母的评论,这只会获取父母的孩子,而不是父母的列表,但这取决于您如何设置数据库架构。

以上是关于Firebase .childAdded 和活动指示器的主要内容,如果未能解决你的问题,请参考以下文章

Swift Firebase:带有 .childAdded 的 UIRefreshControl

防止在 Swift 中使用 .childAdded 从 Firebase 获取所有数据

Swift -Firebase 如何知道 .childAdded 是不是为空?

Firestore 是不是有相当于 Firebase 的 childAdded(使用 swift)的监听器?

Firebase + Android - 通知 ChildAdded - 如何只获得新的孩子?

当从 Firebase 管理员(nodejs)推送孩子时,Firebase childAdded 观察者不会被触发