Unable to download firebase database to my app - ios

I am new to programming in swift. I am trying to make an app which downloads student data from firebase database. I am unable to get the app running. This is my JSON file:
{"classA":[
{
"name": "Student1",
"USN": "1DS16CS095"
},
{
"name": "student2",
"USN": "1DS16CS065"
},
{
"name":"student3",
"USN":"1DS16CS047"
}
]
}
This is my code to download the above JSON file and put it in tableView. Modelstudent is my class where I have my variables name and USN stored. and marksstudentlistTableViewCell is the class I am using to manipulate the labels of my prototype cell.
import UIKit
import Firebase
import FirebaseDatabase
struct StudentData {
let StudentName : String
let StudentUSN : String
}
class marksstudentlist: UIViewController, UITableViewDelegate, UITableViewDataSource{
var FetchedStudentIDs = [StudentData]()
#IBOutlet weak var tableView: UITableView!
var ref: DatabaseReference!
var _selectedsub: Int!
var selectedsub: Int {
get {
return _selectedsub
}set {
_selectedsub = newValue
}
}
override func viewDidLoad() {
tableView.delegate = self
tableView.dataSource = self
if(classselected==0){
ref = Database.database().reference().child("classA")
ref.observe(DataEventType.value, with: { (snapshot) in
if snapshot.childrenCount>0{
for students in snapshot.children.allObjects as! [DataSnapshot]{
let studentObject = students.value as? [String: String]
let studentname = studentObject?["name"]
let studentUSN = studentObject?["USN"]
let student = Modelstudent(name: studentname , USN: studentUSN)
self.FetchedStudentIDs.insert(StudentData(StudentName :(studentname as? String!)! , StudentUSN : (studentUSN as? String!)! ) , at: 0)
}
self.tableView.reloadData()
}
})
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return FetchedStudentIDs.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "marksstudentlistcell", for: indexPath) as! marksstudentlistTableViewCell
cell.namelbl.text = FetchedStudentIDs[indexPath.row].StudentName// Student name comes from Firebase
cell.USNlbl.text = FetchedStudentIDs[indexPath.row].StudentUSN
return cell
}
#IBAction func backbtn(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}

Using Swift Struct is the best way to get your firebase data inside the tableView,
Let's Get started
on your TableView swift file, above the class and stuff paste this
Struct StudentData {
let StudentObject : String // If it's
let StudentName : String // It returns a string right?
let StudentUSN : String
// do the others.
}
okay so then create a var just down below the class call it
var FetchedStudentIDs = [StudentData]()
then you got the reading method from firebase
ref = Database.database().reference().child("classA")
ref.observe(DataEventType.value, with: { (snapshot) in
if snapshot.childrenCount>0{
self.studentslist.removeAll()
for students in snapshot.children.allObjects as! [DataSnapshot]{
let studentObject = students.value as? [String: AnyObject]
let studentname = studentObject?["name"]
let studentUSN = studentObject?["USN"]
let student = Modelstudent(name: studentname as! String?, USN: studentUSN as! String?) //storing in Modelstudent class
self.
FetchedStudentIDs.insert(StudentData(studentname:StudentName as! String , studentUSN : StudentUSN as! String ) , at: 0) // Student name comes from the struct Above, do the others as this
}
self.tableView.reloadData() // make sure you call this
}
})
return your tableView
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return FetchedStudentIDs.count
}
your CellForRowAtIndexPath
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
cell.exampleLabel.text = FetchedStudentIDs[Indexpath.row].StudentName// Student name comes from Firebase
return cell
}
Hope this Helps

Related

Swift TableView ImageView + Label = Fatal Error: Index out of range

I am using a tableview to show a Project's title including the image.
I'm using FirebaseStorage and FirebaseDatabase.
The Problem is, that when I have only one protect, I get "Fatal error: Index out of range", as soon as I click on the Title.
When I have more than one Project you can see what happens in the video.
Maybe someone can help me, since something isn't right with the index handling. :)
import UIKit
import Kingfisher
import Foundation
import FirebaseStorage
import FirebaseDatabase
class HomeViewController: UIViewController {
// MARK: - Properties
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var addProject: UIButton!
var posts = [Post]()
var textToBeSent: String = ""
override func viewDidLoad() {
super.viewDidLoad()
UserService.posts(for: User.current) { (posts) in
self.posts = posts
self.tableView.reloadData()
}
Utilities.addShadowtoButton(addProject)
}
func configureTableView() {
// remove separators for empty cells
tableView.tableFooterView = UIView()
// remove separators from cells
tableView.separatorStyle = .none
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toDetails" {
let destVC = segue.destination as! ShowProjectDetailsViewController
destVC.post = sender as? Post
}
}
}
extension Collection where Indices.Iterator.Element == Index {
public subscript(safe index: Index) -> Iterator.Element? {
return (startIndex <= index && index < endIndex) ? self[index] : nil
}
}
// MARK: - UITableViewDataSource
extension HomeViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let post = posts[indexPath.row]
performSegue(withIdentifier: "toDetails", sender: post)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func numberOfSections(in tableView: UITableView) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let post = posts[indexPath.section]
switch indexPath.row {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "PostImageCell") as! PostImageCell
let imageURL = URL(string: post.imageURL)
cell.postImageView.kf.setImage(with: imageURL)
return cell
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: "PostSubCell") as! PostSubCell
cell.projectName.text = post.projectTitle
return cell
default:
fatalError("Error: unexpected indexPath.")
}
}
}
// MARK: - UITableViewDelegate
extension HomeViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath.row {
case 0:
let post = posts[indexPath.section]
return post.imageHeight
case 1:
return PostSubCell.height
default:
fatalError()
}
}
}
import Foundation
import FirebaseAuth.FIRUser
import FirebaseDatabase
import FirebaseUI
import FirebaseAuth
struct UserService {
static func posts(for user: User, completion: #escaping ([Post]) -> Void) {
let ref = Database.database().reference().child("posts").child(user.uid)
ref.observe(DataEventType.value, with: { (snapshot) in
guard let snapshot = snapshot.children.allObjects as? [DataSnapshot] else {
return completion([])
}
let posts = snapshot.reversed().compactMap(Post.init)
completion(posts)
})
}
}
import Foundation
import UIKit
import FirebaseDatabase.FIRDataSnapshot
class Post {
// Next let's add properties to store all the additional information we need. Add the following to your post class.
var key: String?
let imageURL: String
let imageHeight: CGFloat
let creationDate: Date
let imageName: String
let projectTitle: String
let projectLocation: String
let projectDescription: String
let projectBeginn: String
let projectEnd: String
// You'll get some compiler errors for not having any initializers or default values for certain properties. Let's go ahead and fix that:
init(imageURL: String, imageName: String, imageHeight: CGFloat, projectTitle: String, projectLocation: String, projectDescription: String, projectBeginn: String, projectEnd: String) {
self.imageURL = imageURL
self.imageName = imageName
self.imageHeight = imageHeight
self.creationDate = Date()
self.projectTitle = projectTitle
self.projectLocation = projectLocation
self.projectDescription = projectDescription
self.projectBeginn = projectBeginn
self.projectEnd = projectEnd
}
var dictValue: [String : Any] {
let createdAgo = creationDate.timeIntervalSince1970
return ["image_url" : imageURL,
"image_name" : imageName,
"image_height" : imageHeight,
"created_at" : createdAgo,
"projectTitle" : projectTitle,
"projectLocation" : projectLocation,
"projectDescription" : projectDescription,
"projectBeginn" : projectBeginn,
"projectEnd": projectEnd ]
}
init?(snapshot: DataSnapshot) {
guard let dict = snapshot.value as? [String : Any],
let imageURL = dict["image_url"] as? String,
let imageName = dict["image_name"] as? String,
let imageHeight = dict["image_height"] as? CGFloat,
let createdAgo = dict["created_at"] as? TimeInterval,
let projectTitle = dict["projectTitle"] as? String,
let projectLocation = dict["projectLocation"] as? String,
let projectDescription = dict["projectDescription"] as? String,
let projectBeginn = dict["projectBeginn"] as? String,
let projectEnd = dict["projectEnd"] as? String
else { return nil }
self.key = snapshot.key
self.imageURL = imageURL
self.imageName = imageName
self.imageHeight = imageHeight
self.creationDate = Date(timeIntervalSince1970: createdAgo)
self.projectTitle = projectTitle
self.projectLocation = projectLocation
self.projectDescription = projectDescription
self.projectBeginn = projectBeginn
self.projectEnd = projectEnd
}
}
Thanks for your help!
You created your numberOfSection by [Post]. And also you assigning performSegue on click of indexPath.row. So it's throws an error, you've to use indexPath.section instead of indexPath.row in didSelectItem() method
e.g.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let post = posts[indexPath.section] // Use here section instead of row
performSegue(withIdentifier: "toDetails", sender: post)
}

Grouping an array from firestore in Swift

I have a firestore database that has a number of orders in a restaurant app. I want to group these orders by the table number so as to present the user with a bill/check for each table number.
I have spent a lot of time researching it and I believe I need to using Dictionary and Grouping. As you will see from the code below I have made an attempt which I think might be close.
Here is how my data is structured in firestore:
Here is my bill struct:
import Foundation
struct Bill {
var billID: String
var userID: String
var tableNumber: String
var itemsOrdered: [[String: Any]]
}
And here is my main view controller:
import FirebaseAuth
import FirebaseFirestore
import UIKit
class BillsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var billTable: UITableView!
var billsArray = [Bill]()
var groupedBills = [[Bill]]()
let db = Firestore.firestore()
func getData() {
let userID = Auth.auth().currentUser!.uid
db.collection("Orders")
.whereField("User_ID", isEqualTo: userID)
.whereField("Order_Complete", isEqualTo: true)
.addSnapshotListener { querySnapshot, error in
if let error = error {
print("Error:\(error.localizedDescription)")
} else {
self.billsArray.removeAll()
for document in querySnapshot!.documents {
let userID = document.get("User_ID") as! String
let tableNumber = document.get("Table_Number") as! String
let docID = document.documentID
let itemsOrdered = document.get("Items_Ordered") as! [[String: Any]]
let bill = Bill(billID: docID, userID: userID, tableNumber: tableNumber, itemsOrdered: itemsOrdered)
self.billsArray.append(bill)
}
}
let groupedDictionaryInFunc = Dictionary(grouping: self.billsArray) { (bill) -> String in
bill.tableNumber
}
print(self.groupedBills)
let keys = groupedDictionaryInFunc.keys.sorted()
print("Keys\(keys)")
keys.forEach {
self.groupedBills.append(groupedDictionaryInFunc[$0]!)
}
}
billTable.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("From table func: \(groupedBills)")
return groupedBills[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "billCell", for: indexPath)
let bill = groupedBills[indexPath.section][indexPath.row]
cell.textLabel?.text = "\(bill.itemsOrdered)"
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return groupedBills.count
}
override func viewDidLoad() {
super.viewDidLoad()
getData()
billTable.delegate = self
billTable.dataSource = self
}
}
The expected (or desired!) result is it populates my tableview with each section title the table number and then the the contents of the section being the items that were ordered.
Currently I'm getting a blank and my grouped array appears to be empty.
Any help would be appreciated!

How to group tableview cells based on field in JSON array

Essentially I have am using JSON data to create an array and form a tableview.
I would like the table cells to be grouped by one of the fields from the JSON array.
This is what the JSON data looks like:
[{"customer":"Customer1","number":"122039120},{"customer":"Customer2","number":"213121423"}]
Each number needs to be grouped by each customer.
How can this be done?
This is how I've implemented the JSON data using the table:
CustomerViewController.swift
import UIKit
class CustomerViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, FeedCustomerProtocol {
var feedItems: NSArray = NSArray()
var selectedStock : StockCustomer = StockCustomer()
let tableView = UITableView()
#IBOutlet weak var customerItemsTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
//set delegates and initialize FeedModel
self.tableView.allowsMultipleSelection = true
self.tableView.allowsMultipleSelectionDuringEditing = true
self.customerItemsTableView.delegate = self
self.customerItemsTableView.dataSource = self
let feedCustomer = FeedCustomer()
feedCustomer.delegate = self
feedCustomer.downloadItems()
}
}
func itemsDownloaded(items: NSArray) {
feedItems = items
self.customerItemsTableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of feed items
print("item feed loaded")
return feedItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Retrieve cell
let cell = tableView.dequeueReusableCell(withIdentifier: "customerGoods", for: indexPath) as? CheckableTableViewCell
let cellIdentifier: String = "customerGoods"
let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
// Get the stock to be shown
let item: StockCustomer = feedItems[indexPath.row] as! StockCustomer
// Configure our cell title made up of name and price
let titleStr = [item.number].compactMap { $0 }.joined(separator: " - ")
return myCell
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
let cellIdentifier: String = "customerGoods"
let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
myCell.textLabel?.textAlignment = .left
}
}
FeedCustomer.swift:
import Foundation
protocol FeedCustomerProtocol: class {
func itemsDownloaded(items: NSArray)
}
class FeedCustomer: NSObject, URLSessionDataDelegate {
weak var delegate: FeedCustomerProtocol!
let urlPath = "https://www.example.com/example/test.php"
func downloadItems() {
let url: URL = URL(string: urlPath)!
let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
let task = defaultSession.dataTask(with: url) { (data, response, error) in
if error != nil {
print("Error")
}else {
print("stocks downloaded")
self.parseJSON(data!)
}
}
task.resume()
}
func parseJSON(_ data:Data) {
var jsonResult = NSArray()
do{
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
} catch let error as NSError {
print(error)
}
var jsonElement = NSDictionary()
let stocks = NSMutableArray()
for i in 0 ..< jsonResult.count
{
jsonElement = jsonResult[i] as! NSDictionary
let stock = StockCustomer()
//the following insures none of the JsonElement values are nil through optional binding
if let number = jsonElement[“number”] as? String,
let customer = jsonElement["customer"] as? String,
{
stock.customer = customer
stock.number = number
}
stocks.add(stock)
}
DispatchQueue.main.async(execute: { () -> Void in
self.delegate.itemsDownloaded(items: stocks)
})
}
}
StockCustomer.swift:
import UIKit
class StockCustomer: NSObject {
//properties of a stock
var customer: String?
var number: String?
//empty constructor
override init()
{
}
//construct with #name and #price parameters
init(customer: String) {
self.customer = customer
}
override var description: String {
return "Number: \(String(describing: number)), customer: \(String(describing: customer))"
}
}
You can achieve this by making an array of array. So something like this
[[{"customer": "customer1", "number": "123"}, {"customer": "customer1", "number": "456"}], [{"customer": "customer2", "number": "678"}, {"customer": "customer2", "number": "890"}]]
This is not the only data structure you can use to group. Another possibility is:
{"customer1": [{"customer": "customer1", "number": "123"}, {"customer": "customer1", "number": "456"}], "customer2": [{"customer": "customer2", "number": "678"}, {"customer": "customer2", "number": "890"}]}
Then you can use UITableView sections to group by customers. Section count would be the number of inside arrays and each section would contain as many rows as there are numbers in that inside array.
You can group a sequence based on a particular key using one of the Dictionary initializer,
init(grouping:by:)
The above method init will group the given sequence based on the key you'll provide in its closure.
Also, for parsing such kind of JSON, you can easily use Codable instead of manually doing all the work.
So, for that first make StockCustomer conform to Codable protocol.
class StockCustomer: Codable {
var customer: String?
var number: String?
}
Next you can parse the array like:
func parseJSON(data: Data) {
do {
let items = try JSONDecoder().decode([StockCustomer].self, from: data)
//Grouping the data based on customer
let groupedDict = Dictionary(grouping: items) { $0.customer } //groupedDict is of type - [String? : [StockCustomer]]
self.feedItems = Array(groupedDict.values)
} catch {
print(error.localizedDescription)
}
}
Read about init(grouping:by:) in detail here: https://developer.apple.com/documentation/swift/dictionary/3127163-init
Make the feedItems object in CustomerViewController of type [[StockCustomer]]
Now, you can implement UITableViewDataSource methods as:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.feedItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customerGoods", for: indexPath) as! CheckableTableViewCell
let items = self.feedItems[indexPath.row]
cell.textLabel?.text = items.compactMap({$0.number}).joined(separator: " - ")
//Configure the cell as per your requirement
return cell
}
Try implementing the approach with all the bits and pieces and let me know in case you face any issues.

How to check and delete duplicates values in TableView?

I have a database on Firebase and a tableview.
I have a list of brands, models, and year for motorcycles and I want to retrieve the list of brands on the tableview.
The problem is the DB has duplicates values. There is more than one motorcycle from Suzuki, there is more one models of SV 650, etc.
How can I check duplicates values, put it in a new array, and retrieve it in the tableview?
This is my TableViewController file:
import UIKit
import FirebaseAuth
import FirebaseDatabase
class SelectionMarqueViewController: UITableViewController {
var posts = [Post]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
loadMarques()
}
func loadMarques() {
var ref : DatabaseReference?
ref = Database.database(url: "https://myride-test.firebaseio.com/").reference()
ref?.observe(.childAdded, with: { (snapshot) in
if let dict = snapshot.value as? [String: Any] {
let MarqueText = dict["Marque"] as! String
let post = Post(MarqueText: MarqueText)
self.posts.append(post)
print(self.posts)
self.tableView.reloadData()
}
})
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath)
cell.textLabel?.text = posts[indexPath.row].Marque
return cell
}
}
And this one is the file with the Post func:
import Foundation
class Post {
var Marque: String
init(MarqueText: String) {
Marque = MarqueText
}
}
Here my Firebase Database:
Actually the tableview shows the complete list of brands in the DB, and so, many times the same brands.
On the DB and code:
"Marque" correspond to the brand.
You can implement Hashable
class Post : Hashable {
var marque: String
init(marqueText: String) {
marque = marqueText
}
// Equatable for contains
static func == (lhs:Post,rhs:Post) -> Bool {
return lhs.marque == rhs.marque
}
// Hashable for Set
var hashValue:Int {
return marque.hashValue
}
}
and use
if let dict = snapshot.value as? [String: Any] {
let MarqueText = dict["Marque"] as! String
let post = Post(MarqueText: MarqueText)
self.posts.append(post)
self.posts = Array(Set(self.posts))
print(self.posts)
self.tableView.reloadData()
}
Or simply
let marqueText = dict["Marque"] as! String
if !self.posts.map { $0.marqueText}.contains(marqueText) {
let post = Post(marqueText:marqueText)
self.posts.append(post)
self.tableView.reloadData()
}
Check and append if the marque is not available in the datasource of the tableview.
func appendMarqueAndReloadIfNeeded(_ marque: String) {
if self.posts.map({ $0.Marque }).contains(marque) {
// Do nothing
} else {
self.posts.append(Post(MarqueText: marque))
self.tableView.reloadData()
}
}
Then you call it inside observe:
///....
if let dict = snapshot.value as? [String: Any] {
let MarqueText = dict["Marque"] as! String
self.appendMarqueAndReloadIfNeeded(MarqueText)
}
///....

I tried to retrieving data from firebase database to tableview but I just got one element

I tried to retrieving data from Firebase database to tableview in Xcode
but I just got one element even if I have a lot of element in the database.
I followed a tutorial, I put return sonsList.count to numberOfRowsInSection as suppose but nothing happen.
Here is my code:
import UIKit
import Firebase
import FirebaseDatabase
class sons {
let name : String!
//let place : String!
init(title_String : String!){
self.name = title_String
// self.place = place_String
}
}
class sonsTableViewController: UITableViewController {
var ref:DatabaseReference!
//var sons = [String]()
var newSon: String = ""
let cellId = "cellId"
var refHandel : uint!
var sonsList = [sons]()
override func viewDidLoad() {
super.viewDidLoad()
ref = Database.database().reference()
ref.child("name").queryOrderedByKey().observeSingleEvent(of: .childAdded, with: { snapshot in
let value = snapshot.value as? NSDictionary
let name = value!["name"] as! String
self.sonsList.append(sons(title_String : name))
self.tableView.reloadData()
})
//fetchName()
}
func fetchName() {
}
#IBAction func cancel(segue:UIStoryboardSegue) {
}
#IBAction func done(segue:UIStoryboardSegue) {
var sonDetailVC = segue.source as! addSonViewController
newSon = sonDetailVC.name
// sons.append(newSon)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sonsList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
let label = cell?.viewWithTag(1) as! UILabel
label.text = sonsList[indexPath.row].name
return cell!
}
}
You have issues in your Database query.
You append only one value in sonsList.
ref = Database.database().reference()
ref.child("name").queryOrderedByKey().observeSingleEvent(of: .childAdded, with: { snapshot in
//Parse snapshot value correctly it is array or not.
if let dicValue = snapshot.value as? [String : Any] {
for (key,value) in dicValue {
let name = value["name"] as? String
self.sonsList.append(sons(title_String : name))
}
self.tableView.reloadData()
}
})
Please refer this link for Get data in firebase Database.
https://firebase.google.com/docs/database/ios/read-and-write

Resources