I am creating a tableview with one cell, and retrieving data from Firebase to display as a label firstName. The data is being retrieved (I have checked by using a print statement) however the label is not showing up, even though alpha is set to 1. Any help would be much appreciated.
Here is my code:
import FirebaseDatabase
import FirebaseStorage
import FirebaseAuth
import SwiftKeychainWrapper
class userTableViewController: UITableViewController {
var profileData = [profileStruct]()
let storageRef = Storage.storage().reference()
var databaseRef = Database.database().reference()
var ref: DatabaseReference?
var firstName = ""
var lastName = ""
var email = ""
var phoneNumber = ""
override func viewDidLoad() {
super.viewDidLoad()
getProfile()
// Do any additional setup after loading the view.
// tableView.register(profileCell.self, forCellReuseIdentifier: "ProfileCell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
struct profileStruct {
let email : String!
let phoneNumber : String!
let firstName : String!
let lastName : String!
}
#IBAction func signOut(_ sender: Any) {
KeychainWrapper.standard.removeObject(forKey: "uid")
do {
try Auth.auth().signOut()
} catch let signOutError as NSError {
print ("Error signing out: %#", signOutError)
}
dismiss(animated: true, completion: nil)
}
func getProfile() {
let databaseRef = Database.database().reference()
databaseRef.child("users").queryOrderedByKey().observeSingleEvent(of: .childAdded, with: {
snapshot in
self.firstName = ((snapshot.value as? NSDictionary)!["firstname"] as? String)!
self.lastName = ((snapshot.value as? NSDictionary)!["lastname"] as? String)!
self.email = ((snapshot.value as? NSDictionary)!["email"] as? String)!
self.phoneNumber = ((snapshot.value as? NSDictionary)!["phone number"] as? String)!
print(self.firstName)
DispatchQueue.main.async {
self.tableView.reloadData()
}
})
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// tableView.dequeueReusableCell(withIdentifier: "PostCell")!.frame.size.height
return 500
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileCell") as? profileCell else { return UITableViewCell() }
cell.firstNameLabel?.text = "first name: " + firstName
cell.lastNameLabel?.text = "last name: " + lastName
cell.emailLabel?.text = "email: " + email
cell.phoneNumberLabel?.text = "phone number: " + phoneNumber
return cell
}
}
Add a breakpoint on guard let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileCell") as? profileCell else { return UITableViewCell() }, you need to check whether the as? profileCell is successful, and check whether the Data Source is invoked.
If the first step is working, you need to check the profileCell UI layout. Open the Debug View Hierarchy, and check whether any cell on tableView.
func getProfile() {
let databaseRef = Database.database().reference()
databaseRef.child("users").queryOrderedByKey().observeSingleEvent(of: .childAdded, with: {
snapshot in
self.firstName = ((snapshot.value as? NSDictionary)!["firstname"] as? String)!
self.lastName = ((snapshot.value as? NSDictionary)!["lastname"] as? String)!
self.email = ((snapshot.value as? NSDictionary)!["email"] as? String)!
self.phoneNumber = ((snapshot.value as? NSDictionary)!["phone number"] as? String)!
print(self.firstName)
self.tableView.dataSource = self
self.tableView.delegate = self
self.tableView.reloadData()
})}
You seem to show the email instead of the first name here.
cell.emailLabel?.text = "email: " + firstName
cell.phoneNumberLabel?.text = "phone number: " + lastName
cell.firstNameLabel?.text = "first name: " + email
cell.lastNameLabel?.text = "last name: " + phoneNumber
Related
How should I get the document id upon tapping the UItableViewCell?
I know the below code do give me the row index, but for a feed post I would like to get the document id for the the particular post everytime
I have tried to retrieve the document id through key setup in model file but avail to no good
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("row selected: \(indexPath.row)")
performSegue(withIdentifier: "toDetailView", sender: indexPath)
}
Posts Model
import Foundation
import Firebase
import FirebaseFirestore
protocol DocumentSerializable {
init?(dictionary:[String:Any])
}
struct Post {
var _username: String!
var _postTitle: String!
var _postcategory: String!
var _postContent: String!
var dictionary:[String:Any] {
return [
"username": _username,
//"profile_pic":profile_pic,
"postTitle":_postTitle,
"postcategory":_postcategory,
"postContent":_postContent
]
}
}
extension Post : DocumentSerializable {
init?(dictionary: [String : Any]) {
guard let username = dictionary["username"] as? String,
// let profile_pic = dictionary["profile_pic"] as? String,
let postTitle = dictionary["postTitle"] as? String,
let postcategory = dictionary["postcategory"] as? String,
let postContent = dictionary["postContent"] as? String else { return nil }
self.init( _username: username ,_postTitle: postTitle, _postcategory: postcategory, _postContent: postContent)
}
}
Code to retrieve the collection as whole into. tableview
import Foundation
import UIKit
import Firebase
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView:UITableView!
var posts = [Post]()
var db: Firestore!
var postKey:String = ""
private var documents: [DocumentSnapshot] = []
//public var posts: [Post] = []
private var listener : ListenerRegistration!
override func viewDidLoad() {
super.viewDidLoad()
db = Firestore.firestore()
self.navigationController?.navigationBar.isTranslucent = false
tableView = UITableView(frame: view.bounds, style: .plain)
let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "postCell")
tableView.backgroundColor = UIColor(white: 0.90,alpha:1.0)
view.addSubview(tableView)
var layoutGuide:UILayoutGuide!
if #available(iOS 11.0, *) {
layoutGuide = view.safeAreaLayoutGuide
} else {
// Fallback on earlier versions
layoutGuide = view.layoutMarginsGuide
}
tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
retrieveAllPosts()
//checkForUpdates()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/* override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("toDetailPage", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let indexPath = self.tableView.indexPathForSelectedRow
let person = personList[indexPath!.row]
if segue.identifier == "toDetailPage"{
let DetailBookViewController = (segue.destinationViewController as! DetailPage)
DetailBookViewController.user_name = user_name
DetailBookViewController.user_age = user_age
DetailBookViewController.user_urlPicture = user_urlPicture
}*/
#IBAction func handleLogout(_ sender:Any) {
try! Auth.auth().signOut()
self.dismiss(animated: false, completion: nil)
}
/*func checkForUpdates() {
db.collection("posts").whereField("timeStamp", isGreaterThan: Date())
.addSnapshotListener {
querySnapshot, error in
guard let snapshot = querySnapshot else {return}
snapshot.documentChanges.forEach {
diff in
if diff.type == .added {
self.posts.append(Post(dictionary: diff.document.data())!)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
}*/
func retrieveAllPosts(){
let postsRef = Firestore.firestore().collection("posts").limit(to: 50)
postsRef.getDocuments { (snapshot, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let snapshot = snapshot {
for document in snapshot.documents {
let data = document.data()
self.postKey = document.documentID
let username = data["username"] as? String ?? ""
let postTitle = data["postTitle"] as? String ?? ""
let postcategory = data["postcategory"] as? String ?? ""
let postContent = data["postContent"] as? String ?? ""
let newSourse = Post(_postKey:self.postKey, _username: username, _postTitle: postTitle, _postcategory: postcategory, _postContent: postContent)
self.posts.append(newSourse)
print(self.postKey)
}
self.tableView.reloadData()
}
}
}
}
/* postsRef.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
self.posts = querySnapshot!.documents.flatMap({Post(dictionary: $0.data())})
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}*/
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
cell.set(post: posts[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("row selected: \(indexPath.row)")
//performSegue(withIdentifier: "toDetailView", sender: indexPath)
}
}
Add a new documentId property to your Post struct:
struct Post {
var _username: String!
var _postTitle: String!
var _postcategory: String!
var _postContent: String!
var _documentId: String! // This is new.
var dictionary:[String : Any] {
return [
"documentId" : _documentId, // This is new.
"username": _username,
//"profile_pic":profile_pic,
"postTitle":_postTitle,
"postcategory":_postcategory,
"postContent":_postContent
]
}
}
extension Post : DocumentSerializable
{
init?(dictionary: [String : Any])
{
guard let username = dictionary["username"] as? String,
// let profile_pic = dictionary["profile_pic"] as? String,
let postTitle = dictionary["postTitle"] as? String,
let postcategory = dictionary["postcategory"] as? String,
let documentId = dictionary["documentId"] as? String // This is new.
let postContent = dictionary["postContent"] as? String else { return nil }
self.init( _username: username ,_postTitle: postTitle, _postcategory: postcategory, _postContent: postContent, _documentId: documentId)
}
}
Change your retrieveAllPosts function and set the documentId of the Post instance, do not use the global variable for this:
if let snapshot = snapshot
{
for document in snapshot.documents
{
let data = document.data()
let username = data["username"] as? String ?? ""
let postTitle = data["postTitle"] as? String ?? ""
let postcategory = data["postcategory"] as? String ?? ""
let postContent = data["postContent"] as? String ?? ""
let newSourse = Post(_postKey:self.postKey, _username: username, _postTitle: postTitle, _postcategory: postcategory, _postContent: postContent, _documentId: document.documentId)
self.posts.append(newSourse)
}
}
Now you can access the documentId of the selected Post in didSelectRowAt:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let post = self.posts[indexPath.row]
Swift.print(post.documentId)
// print("row selected: \(indexPath.row)")
// performSegue(withIdentifier: "toDetailView", sender: indexPath)
}
Hopefully this will guide you into the right direction.
I have a tableview that is being populated with who a user is following. Problem is that I need to pass that cells data to "var otherUser: NSDictionary!" but because I am populating the cell using a data structure file called "Information" I get this error - "Cannot assign value of type 'Information' to type 'NSDictionary?'" in the prepareForSegue. I am unsure if I can repackage the information I need into a NSDictionary so I can successfully do a data pass. I just don't know if this is a easy solution or an actual problem because of my ignorance.
Following TableViewController Code
import UIKit
import Firebase
class BusinessFollowing: UITableViewController {
#IBOutlet var noDataView: UIView!
#IBOutlet var followingTableView: UITableView!
var yourFollowing = [Information]()
var listFollowing = [NSDictionary?]()
var databaseRef = Database.database().reference()
let uid = Auth.auth().currentUser?.uid
var loggedInUser = Auth.auth().currentUser
var loggedInUserData:NSDictionary?
var following = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.followingTableView.backgroundView = nil
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.followingTableView.reloadData()
self.yourFollowing.removeAll()
self.following.removeAll()
getFollowingData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if segue.identifier == "following" {
// gotta check if we're currently searching
if let indexPath = followingTableView.indexPathForSelectedRow {
let user = self.yourFollowing[indexPath.row]
let controller = segue.destination as? ExploreBusinessProfileSwitchView
controller?.otherUser = user
}
}
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return self.yourFollowing.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! BusinessFollowingCell
let following = yourFollowing[indexPath.row]
let businessName = following.businessName
let businessStreet = following.businessStreet
let businessCity = following.businessCity
let businessState = following.businessState
cell.businessName.text = businessName
cell.businessStreet.text = businessStreet
cell.businessCity.text = businessCity
cell.businessState.text = businessState
// cell.businessName?.text = self.listFollowing[indexPath.row]?["businessName"] as? String
// cell.businessStreet?.text = self.listFollowing[indexPath.row]?["businessStreet"] as? String
// cell.businessCity?.text = self.listFollowing[indexPath.row]?["businessCity"] as? String
// cell.businessState?.text = self.listFollowing[indexPath.row]?["businessState"] as? String
return cell
}
func getFollowingData() {
self.yourFollowing.removeAll()
self.following.removeAll()
self.followingTableView.reloadData()
Database.database().reference().child("Businesses").child((loggedInUser?.uid)!).child("following").observe(.value, with: { snapshot in
if snapshot.exists() {
MBProgressHUD.showAdded(to: self.view, animated: true)
let databaseRef = Database.database().reference()
databaseRef.child("Businesses").queryOrderedByKey().observeSingleEvent(of: .value, with: { (usersSnapshot) in
let users = usersSnapshot.value as! [String: AnyObject]
for (_, value) in users {
if let userID = value["uid"] as? String {
if userID == Auth.auth().currentUser?.uid {
print(value)
if let followingUsers = value["following"] as? [String : String] {
for (_,user) in followingUsers {
self.following.append(user)
}
}
databaseRef.child("following").queryOrderedByKey().observeSingleEvent(of: .value, with: { (postsSnapshot) in
let posts = postsSnapshot.value as! [String: AnyObject]
for (_, post) in posts {
for (_, postInfo) in post as! [String: AnyObject] {
if let followingID = postInfo["uid"] as? String {
for each in self.following {
if each == followingID {
guard let uid = postInfo["uid"] as! String? else {return}
guard let name = postInfo["businessName"] as! String? else {return}
guard let address = postInfo["businessStreet"] as! String? else {return}
guard let state = postInfo["businessState"] as! String? else {return}
guard let city = postInfo["businessCity"] as! String? else {return}
self.yourFollowing.append(Information(uid: uid, businessName: name, businessStreet: address, businessCity: city, businessState: state))
}
self.followingTableView.backgroundView = nil
self.followingTableView.reloadData()
}
}
}
}
MBProgressHUD.hide(for: self.view, animated: true)
}) { (error) in
print(error.localizedDescription)
}
}
}
}
})
} else {
print("Not following anyone")
self.followingTableView.backgroundView = self.noDataView
MBProgressHUD.hide(for: self.view, animated: true)
}
})
}
}
"Information" Data Structure File
import UIKit
class Information {
var uid: String
var businessName: String
var businessStreet: String
var businessCity: String
var businessState: String
init(uid: String, businessName: String, businessStreet: String, businessCity: String, businessState: String){
self.uid = uid
self.businessName = businessName
self.businessStreet = businessStreet
self.businessCity = businessCity
self.businessState = businessState
}
}
The error is pretty clear.
user in ExploreBusinessProfileSwitchView is obviously declared as NSDictionary, declare it as Information.
By the way don't use NSArray / NSDictionary in Swift. Use native types.
I have my firebase database structured like this:
Snap (-KWLSAIh5WJvNJOkxBEr) {
beschrijving = "description";
image = "link to image";
title = "title";
}
Snap (-KWLSTak0H20X_2Qnanv) {
beschrijving = "description";
image = "link to image";
title = "title";
}
This is the code I am using to display this in a TableView:
import UIKit
import Firebase
class NieuwsTableViewController: UITableViewController {
var users = [UsersII]()
let cellId = "IdCell"
override func viewDidLoad() {
super.viewDidLoad()
fetchUser()
}
func fetchUser() {
Database.database().reference().child("Blog").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let user = UsersII(dictionary: dictionary)
self.users.append(user)
print(snapshot)
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
}, withCancel: nil)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> lllTableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
let user = users.reversed()[indexPath.row]
cell.textLabel?.text = user.name
return cell as! lllTableViewCell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let message = users.reversed()[indexPath.row]
guard let beschrijving = message.beschrijving else {
return
}
guard let image = message.plaatje else {
return
}
guard let titel = message.name else {
return
}
UserDefaults.standard.set(beschrijving, forKey: "nieuwsBeschrijving")
UserDefaults.standard.set(image,forKey: "nieuwsPlaatje")
UserDefaults.standard.set(titel, forKey: "nieuwsTitel")
self.performSegue(withIdentifier: "gotonews", sender: nil)
}
}
And I don't know if you will need this to answer this question but I'll also post the "UsersII" (defined as users just above the viewDidLoad method) in case this is needed to answer the question.
import UIKit
class UsersII: NSObject {
var name: String?
var beschrijving: String?
var plaatje: String?
init(dictionary: [String: Any]) {
self.name = dictionary["title"] as? String ?? ""
self.beschrijving = dictionary["beschrijving"] as? String ?? ""
self.plaatje = dictionary["image"] as? String ?? ""
}
}
so what I want to achieve is that if you click on one of the cells, you get the parent id of the article, so in this case that would be the "-KWLSAIh5WJvNJOkxBEr or -KWLSTak0H20X_2Qnanv" I mentioned above in my firebase database structure.
Here is what i was saying you to do:
Your model class:
class UsersII: NSObject {
var parentId: String?
var name: String?
var beschrijving: String?
var plaatje: String?
init(dictionary: [String: Any],parentId:String) {
self.name = dictionary["title"] as? String ?? ""
self.beschrijving = dictionary["beschrijving"] as? String ?? ""
self.plaatje = dictionary["image"] as? String ?? ""
self.parentId = parentId
}
}
Fetch user method:
func fetchUser() {
Database.database().reference().child("Blog").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let user = UsersII(dictionary: dictionary,parentId:snapshot.key)
self.users.append(user)
print(snapshot)
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
}, withCancel: nil)
}
And finaly you didSelect:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let message = users.reversed()[indexPath.row]
guard let beschrijving = message.beschrijving else {
return
}
guard let image = message.plaatje else {
return
}
guard let titel = message.name else {
return
}
guard let parentId = message.name else
{
return
}
UserDefaults.standard.set(beschrijving, forKey: "nieuwsBeschrijving")
UserDefaults.standard.set(image,forKey: "nieuwsPlaatje")
UserDefaults.standard.set(titel, forKey: "nieuwsTitel")
UserDefaults.standard.set(parentId,forKey: "nieuwsParentId")
self.performSegue(withIdentifier: "gotonews", sender: nil)
}
}
I have been stuck on this bug for the past 5 hours I Really need some help. I am making a chat application that has private messaging. When a user sends a text everything works great. But when a use trys to reply to a message another user sent , things get weird.
the user duplicates, along with failing to update time and the most recent text! whats going on! here is the code
Message controller: loads the message users from which firebase provides I know this could have potentially been an uploading to firebase issue, where their are two children but my firebase looks fine, NO duplicates on the back end. The error ive narrowed it down to being in this class when loading these custom cells into a table view! how do i force it to stop duplicating and rather load the correct one? Thank you so much!
import UIKit
import Firebase
class MessagesViewController: UIViewController , UITableViewDelegate
, UITableViewDataSource{
#IBOutlet weak var messagesLabelOutlet: UILabel!
#IBOutlet weak var messagesTableView: UITableView!
var newUser : User?
var messageArr = [Message]()
var messageDict = [String: Message]()
override func viewDidLoad() {
super.viewDidLoad()
messagesTableView.dataSource = self
messagesTableView.delegate = self;
self.messagesTableView.register(UserCell.self, forCellReuseIdentifier: "cellId")
checkIfUserIsLoggedIn()
messageArr.removeAll()
messageDict.removeAll()
messagesTableView.reloadData()
observeUserMessages()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messageArr.count;
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 72;
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.newUser = User()
if let chatPartnerId = messageArr[indexPath.row].chatPartnerId(){
self.newUser?.toId! = chatPartnerId;
let chatPartnerDataRef = Database.database().reference().child("users").child(chatPartnerId)
chatPartnerDataRef.observeSingleEvent(of: .value) { (snapshot) in
guard let dict = snapshot.value as? [String : AnyObject] else{
return
}
self.newUser?.userName = dict["username"] as? String
self.newUser?.picURL = dict["pic"] as? String
self.newUser?.score = dict["score"] as? String
self.performSegue(withIdentifier:
"goToChatLogControllerPlzFromMessages", sender: self)
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! UserCell
let message = messageArr[indexPath.row]
let totalSection = tableView.numberOfSections
cell.textLabel?.font = UIFont(name: "Avenir Book" , size: 19);
cell.detailTextLabel?.font = UIFont(name: "Avenir Light" , size: 14);
cell.message = message;
return cell;
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// do not remove
if segue.identifier == "goToChatLogControllerPlzFromMessages"{
print("going to chat log")
let recieveVC = segue.destination as! ChatLogController
if let textUser = newUser{
recieveVC.user = textUser;
}
}
}
func checkIfUserIsLoggedIn()
{
if Auth.auth().currentUser?.uid == nil{
print("uid is nil")
performSegue(withIdentifier: "noUserFoundGoingBackToLogin", sender: self);
}
else{
let uid = Auth.auth().currentUser?.uid
Database.database().reference().child("users").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
})
}
}
func observeUserMessages(){
print("NEW USER \(newUser?.userName)")
print("MESSAGE ARR \(messageArr)")
print("MESSAGE DICT\(messageDict.values)")
guard let uid = Auth.auth().currentUser?.uid else{
checkIfUserIsLoggedIn()
return;
}
let ref = Database.database().reference().child("user-messages").child(uid)
ref.observe(.childAdded) { (snapshot) in
let messageId = snapshot.key
let messagesRef = Database.database().reference().child("messages").child(messageId)
messagesRef.observeSingleEvent(of: .value, with: { (snapshot) in
if let dict = snapshot.value as? [String : AnyObject]
{
let message = Message()
message.fromId = dict["fromid"] as? String;
message.text = dict["text"] as? String;
message.timestamp = dict["timestamp"] as? String;
message.toId = dict["toid"] as? String;
self.messageArr.append(message)
if let toID = message.toId{
self.messageDict[toID] = message;
self.messageArr = Array(self.messageDict.values)
self.messageArr.sort(by: { (message1, message2) -> Bool in
let time1 = Int(truncating: (message1.timestamp?.numberValue)!)
let time2 = Int(truncating: (message2.timestamp?.numberValue)!)
return time1 > time2
})
}
DispatchQueue.main.async {
print(message.text!)
self.messagesTableView.reloadData()
}
}
})
}
I have a Firebase database with structure:
"users"
-uid
- name
- email
. I would like to input the "users" email and name into a UITableviewController tableview in XCode. The data can be seen in my console, but is not appended to my Table View
class DictionaryTableViewController: UITableViewController {
var ref: FIRDatabaseReference!
let cellID = "Cell"
var refHandle: UInt!
var userList = [Users]()
override func viewDidLoad() {
super.viewDidLoad()
//Set firebase database reference
ref = FIRDatabase.database().reference()
//Retrieve posts and listen for changes
refHandle = ref?.child("users").observe(.childAdded, with: { (snapshot) in
//Code that executes when child is added
if let dict = snapshot.value as? [String: AnyObject] {
let user = Users()
user.name = snapshot.childSnapshot(forPath: "name").value as? String
print(user.name)
user.email = snapshot.childSnapshot(forPath: "email").value as? String
print(user.email)
print("databaseHandle was called")
for user in self.userList {
print(user)
self.userList.append(user)
}
self.tableView.reloadData()
}
})
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellID)
cell.textLabel?.text = userList[indexPath.row].name.self
cell.textLabel?.text = userList[indexPath.row].email.self
return cell
}
}
}
Remove this:
self.tableView.reloadData()
And after the if let statements add this:
DispatchQueue.main.async{
self.tableView.reloadData()
}
Like so; does not show the data on the table still.
//Retrieve posts and listen for changes
func fetchUserData(with completion:#escaping (Bool)->()) {
refHandle = ref?.child("users").observe(.childAdded, with: {
(snapshot) in
//Code that executes when child is added
if (snapshot.value as? [String: AnyObject]) != nil {
let user = Users()
user.name = snapshot.childSnapshot(forPath: "name").value as?
String
print(user.name)
DispatchQueue.main.async{
user.email = snapshot.childSnapshot(forPath: "email").value
as? String
print(user.email)
print("databaseHandle was called")
for user in self.userList {
print(user)
self.userList.append(user)
self.userTable.reloadData()
}