I am currently having troubling reading and displaying my firebase database into a table list. Below is the code I am using in its current View Controller.
import UIKit
import Firebase
import FirebaseDatabase
class Buy_1: UIViewController, UITableViewDataSource,
UITableViewDelegate {
var ref: DatabaseReference!
var databaseHandle: DatabaseHandle!
var postItem: [String] = []
@IBOutlet weak var TableView: UITableView!
@IBAction func goBackToOneButtonTapped(_ sender: Any) {
performSegue(withIdentifier: "unwindSegueToVC1", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
if FirebaseApp.app() == nil {
FirebaseApp.configure()
}
//Set Self as tableview's data source and delegate
self.TableView.delegate = self
self.TableView.dataSource = self
//Set the firebase reference
ref = Database.database().reference()
//Retrieve and listen for changes
databaseHandle = ref?.child ("items").observe(.childAdded, with: { (snapshot) in
//Convert value of data into string
if let item = snapshot.value as? String
{
self.postItem.append(item)
self.TableView.reloadData()
self.ref?.keepSynced(true)
}
/*if let actualItem = item {
//Appends data to our Item Array
self.postItem.append(actualItem)
//Reload TableView
self.TableView.reloadData()
}*/
})
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
//MARK: - UITableView Delegate Methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postItem.count
}
func tableView(_ TableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = TableView.dequeueReusableCell(withIdentifier: "BasicCell", for: indexPath)
cell.textLabel?.text = postItem[indexPath.row]
return cell
}
}
I do not receive any errors in the code so I am not sure what is wrong. & I have already set the database rules to true.
Thank you.
You are observing .childAdded
, which will trigger your block only when a child is being added to your observed tree of data. Change it to .value
.
The issue in the code is that the children of items are not strings. They in themselves are childSnapshots or key:value pairs.
Here's some example code to read just the itemName from a structure similar to yours
items
item_0
itemName: "Josh"
item_1
itemName: "Screaming Eagle"
item_2
itemName: "Insignia"
and the code to print the key of each child node and the itemName
let ref = self.ref.child("items")
ref.observe(.childAdded, with: { snapshot in
if snapshot.exists() {
let dict = snapshot.value as! [String: Any]
let itemName = dict["itemName"] as? String ?? "No Item Name"
print(snapshot.key, itemName)
}
})
and the output
item_0 Josh
item_1 Screaming Eagle
item_2 Insignia
Note that I used a nil coalescing operator (the ??) to populate the itemName in case it was not found.
I am treating the value portion of the snapshot as a dictionary to allow you to access the child nodes but you could also accomplish that with .childSnapshot like this
let i = snapshot.childSnapshot(forPath: "itemName").value as? String ?? "No Item"
The snapshot.exists is extraneous in this specific example but it should be used with reading by .value.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.