如何实现一个 Firebase 监听器来观察数据库的实时变化

Posted

技术标签:

【中文标题】如何实现一个 Firebase 监听器来观察数据库的实时变化【英文标题】:How to implement a Firebase Listener for observing real time changes in database 【发布时间】:2020-01-16 09:03:23 【问题描述】:

我无法理解如何实现侦听器,以便我可以观察数据库中的变化并将它们实时反映到表视图中。我想观察 isOnline 和 isHorizo​​ntal 的变化,根据该变化我将更改标签值以及图像值。这是我的代码:

var userInfoArray : [UserModel] = [UserModel]()

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view.
      // readData()
        tableView.dataSource = self
        tableView.delegate = self
        self.tableView.rowHeight = 70
       retrieveUserInfo()

    


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
//        print(emailModified.count)
        return userInfoArray.count

    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! TableViewCell
        cell.userLbl.text = "User \([userInfoArray[indexPath.row].email].count)"
        if userInfoArray[indexPath.row].isHorizontal == true 
            cell.messageLbl.text = "I am Horizontal"
         else 
            cell.messageLbl.text = ""
        

        if userInfoArray[indexPath.row].isOnline == true 

            cell.onlineImage.image = UIImage(named: "online")
        else 
            cell.onlineImage.image = UIImage(named: "offline")
        
        return cell

    
     func retrieveUserInfo() 
     Database.database().reference().child("new user").observeSingleEvent(of: .value)  (snapshot) in
        for child in snapshot.children.allObjects as! [DataSnapshot] 
            print(child.children)
        // this will iterate through all children in snapshot at at path specified.
            if let userList = child.value as? Dictionary <String,Any> 

                    let email = userList["email"]
                    print(email)
                    let onlineStatus = userList["isOnline"] as! Any
                    let horizontalStatus = userList["isHorizontal"] as! Any

                    let list = UserModel()
                    list.email = email as? String ?? "nil"
                    print(list.email)
                    list.isHorizontal = horizontalStatus  as! Bool
                    list.isOnline = onlineStatus  as!   Bool

                    self.userInfoArray.append(list)
                    print(self.userInfoArray)

            
            self.tableView.reloadData()
        
        

【问题讨论】:

【参考方案1】:

我找到了解决办法...

func retrieveUserInfo() 

     Database.database().reference().child("new user").observe(of: 
     DataSnapShot.value)  (snapshot) in
        for child in snapshot.children.allObjects as! [DataSnapshot] 
            print(child.children)
        // this will iterate through all children in snapshot at at path specified.
            if let userList = child.value as? Dictionary <String,Any> 

                    let email = userList["email"]
                    print(email)
                    let onlineStatus = userList["isOnline"] as! Any
                    let horizontalStatus = userList["isHorizontal"] as! Any

                    let list = UserModel()
                    list.email = email as? String ?? "nil"
                    print(list.email)
                    list.isHorizontal = horizontalStatus  as! Bool
                    list.isOnline = onlineStatus  as!   Bool

                    self.userInfoArray.append(list)
                    print(self.userInfoArray)

            
            self.tableView.reloadData()
        
        

我之前观察过一个事件,当数据库发生变化时,oberver(DataSnapShot.value) 会通知和观察者。

【讨论】:

【参考方案2】:

.childAdded 给你一一记录。所以在完成处理程序的帮助下取回数据并将数据放入数组中。

Firebase 文档:https://firebase.google.com/docs/database/ios/lists-of-data

示例代码:

func getChatMessages() 
    _firebase.getChatMessages(uniqueId: chatHeadVM.uniqueId)  (messageModel) in
        DispatchQueue.main.async 
            guard let msgModel = messageModel as? MessageModel else 
                return
            

            self.messageList.append(MessageViewModel(messageInfo: msgModel))
//Reload your table
        
    


func getChatMessages(uniqueId: String, completionHandlerWithResponseData: @escaping completionHandlerWithResponseData) 
            let query = ref.child(Firebase.chatNodeStr).child(uniqueId)

        query.observe(.childAdded, with:  snapshot in
            if  let dict = snapshot.value as? [String: Any] 
                let messageModel = MessageModel(withDictionary: dict)
                completionHandlerWithResponseData(messageModel)
            
        )  (error) in
            print(error.localizedDescription)
            completionHandlerWithResponseData(nil)
        
    

希望对您有所帮助。

【讨论】:

以上是关于如何实现一个 Firebase 监听器来观察数据库的实时变化的主要内容,如果未能解决你的问题,请参考以下文章

Swift viewcontroller firebase 数据库观察者重复调用

如何检测firebase观察childAdded在达到queryLimit时停止调用?

如何仅观察 Firebase 中的最后一个字符

一个基于Socket的http请求监听程序实现

vue的数据双向绑定是怎么实现的

如何实现Application event,观察者模式