简体   繁体   中英

Swift 2 Firebase TableView

I am a newbie to swift and firebase, I am trying to populate my tabelview with firebase data. When I run the program, nothing shows up in tableview. Any help would be gladly appreciated. This is what I got do far, tried to read the documents, but its not helping.

import UIKit
import Firebase
import FirebaseUI


class ChurchTableViewController: UITableViewController {


let firebase = Firebase(url:"https://.....com/")

var items = [NSDictionary]()

override func viewDidLoad() {
    super.viewDidLoad()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
     //self.navigationItem.rightBarButtonItem = self.editButtonItem()
}

override func viewDidAppear(animated: Bool) {

    //MARK: Load data from firebsr
    firebase.observeEventType(.Value, withBlock: { snapshot in
        print(snapshot.value)
        }, withCancelBlock: { error in
            print(error.description)
    })

}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(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 items.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

    let dict = items[indexPath.row]
    cell.textLabel?.text = dict["ChurchName"] as? String

    return cell
}

You've created the observer for when some value changes in your Firebase DB, but in your closure you need to add the new items and of course reload your UITableView to synchronize the data in your app, see the following code to see a sample of how to do it with a sample data type too:

var items = [GroceryItem]()

override func viewDidAppear(animated: Bool) {
     super.viewDidAppear(animated)

     firebase.observeEventType(.Value, withBlock: { snapshot in
        var newItems = [GroceryItem]()

        for item in snapshot.children {
          let itemType = GroceryItem(snapshot: item as! FDataSnapshot)
          newItems.append(itemType)
        }

        // update your item with the new ones retrieved
        self.items = newItems

        // reload the data
       self.tableView.reloadData()
    })
}

In the below struct you can see a sample of how you can create your data type from the data returned from Firebase

GroceryItem

struct GroceryItem {

   let key: String!
   let name: String!
   let addedByUser: String!
   let ref: Firebase?
   var completed: Bool!

   // Initialize from arbitrary data
   init(name: String, addedByUser: String, completed: Bool, key: String = "") {
     self.key = key
     self.name = name
     self.addedByUser = addedByUser
     self.completed = completed
     self.ref = nil
   }

   init(snapshot: FDataSnapshot) {
     key = snapshot.key
     name = snapshot.value["name"] as! String
     addedByUser = snapshot.value["addedByUser"] as! String
     completed = snapshot.value["completed"] as! Bool
     ref = snapshot.ref
   }
}

For a deeper knowledge about how to use Firebase you can read this very good tutorial:

I hope this help you.

Check that you have set your Tableview's delegate and datasource properly, to do this, go to interface builder, cmd + right click on your tableview and drag over to the yellow heading icon in interface builder.

You should see two options, 'datasource' and 'delegate', make sure that they are both checked and then rerun your app, you should see the table populate with whatever data you've loaded

You've got three issues

1) Your not populating a datasource for your tableview. This is typically an array that is stored in the class and because it's by .value you will need to iterate over those values to get to each child nodes data

2) You are observing by .value. This will return everything in the node, all children, their children etc so you won't be able to directly read it as a string value unless that's all the node contains, as in a single key:value pair, otherwise all of they key:value pairs will be read.

3) Firebase is asynchronous so within the observe block, you need to populate the array, and then re-load the tableview

Here's the solution:

Given a structure

users    
    user_id_0
       name: "Biff"
    user_id_1
       name: "Buffy"
    user_id_2
       name: "Skip

here's the associated code to read in each name and populate a namesArray

var namesArray: [String] = []

ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
        for child in snapshot.children {
           let name = child.value["name"] as! String
           namesArray.append(name)
        }
        self.myTableView.reloadData()
})

substitute your items array for the namesArray.

They key is to let Firebase load the data asynchronously before telling the tableView to refresh itself, and when using .Value, ensure you iterate over all of the children in that node with snapshot.children

  • This is happened because there is no data in your items array. So first inside your viewDidAppear method you need to append your Firebase data dictionaries into items array and then call tableView.reloadData() .
  • Also check your Firebase database url is correct and you need to fetch and store data in proper format while appending to items array.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM