Ali asghar
Ali asghar

Reputation: 29

How to implement a Firebase Listener for observing real time changes in database

I am having problem understanding how can i implement a listener so that i can observe the changes in database and reflect them to the tableview in real time. I want to observe the changes for isOnline and isHorizontal and according to that change i will change the label value as well image value . here is my code:

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()
        }
        }

Upvotes: 0

Views: 1274

Answers (2)

Ali asghar
Ali asghar

Reputation: 29

I found the solution...

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()
        }
        }

I was observing a single event before and oberver(DataSnapShot.value) notifies and observer when ever a change happen in database.

Upvotes: 1

Mohit Kumar
Mohit Kumar

Reputation: 3086

.childAdded gives you record one by one. so get data back with the help of completion handler and put data into an array.

Firebase Doc for this: https://firebase.google.com/docs/database/ios/lists-of-data

Sample Code:

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)
        }
    }

Hope that helps.

Upvotes: 0

Related Questions