Reputation: 29
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
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
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