Firebase/Swift - 从 Firebase 输出数据出错

Posted

技术标签:

【中文标题】Firebase/Swift - 从 Firebase 输出数据出错【英文标题】:Firebase/Swift - Outputting data from Firebase gone wrong 【发布时间】:2017-11-13 07:57:00 【问题描述】:

我在从 Firbase 正确输出数据时遇到问题。我花了很多时间并尝试了很多不同的方法来做到这一点,创建不同的数据结构等,但我总是会得到崩溃或零输出。我当前的代码正在工作并将数据从 firebase 输出到表格视图中,但是数组未对齐,并且特定用户的一个数组中的字段与另一个不相关,这是不正确的..

我想有更好的方法可以做到这一点,所以任何帮助或指向正确方向的点都将不胜感激。也请对我放轻松,我知道这一点:)

这是我的火力基地结构:

这是我的出租模型:

struct RentalObjects 

    var title: [String : AnyObject] = [:]
    var rentalType: [String : AnyObject] = [:]
    var dateAval: [String : AnyObject] = [:]
    var location: [String : AnyObject] = [:]
    var price: [String : AnyObject] = [:]
    var bond: [String : AnyObject] = [:]
    var pets: [String : AnyObject] = [:]
    var descripton: [String : AnyObject] = [:]


这是我的 VC 输出到表格视图的代码:

import UIKit
import FirebaseDatabase


class RentalTableViewVC: UIViewController, UITableViewDataSource, UITableViewDelegate

    @IBOutlet weak var rentalImage: UIImageView!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var rentalTitle: UILabel!
    @IBOutlet weak var rentalPrice: UILabel!


    var rentalsObject = RentalObjects()
    var databaseRef:DatabaseReference?
    var handle: DatabaseHandle?

    var arrayOfTitles = [String?]()
    var arrayOfBond = [String?]()



    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return rentalsObject.title.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
       let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")

        for (_, value) in rentalsObject.title 
            arrayOfTitles.append(value as? String)

        

        for (_, value) in rentalsObject.bond 

            arrayOfBond.append(value as? String)

        


        cell.textLabel?.text = ("Title: \(String(describing: arrayOfTitles[indexPath.row]!)), Bond: \(String(describing: arrayOfBond[indexPath.row]!))")



        return cell
    


    @IBAction func backPressed(_ sender: Any) 
        dismiss(animated: true, completion: nil)
    

    override func viewDidLoad() 
    super.viewDidLoad()


        databaseRef = Database.database().reference().child("Rentals")
        databaseRef?.observe(DataEventType.value, with:  (snapshot) in

            for rentals in snapshot.children.allObjects as! [DataSnapshot] 





        switch rentals.key 

                case "title" :
                    let titleObj = rentals.value as! [String : AnyObject]

                    self.rentalsObject.title = titleObj

                case "rentalType":
                    let rentalTypeObj = rentals.value as! [String : AnyObject]
                    self.rentalsObject.rentalType = rentalTypeObj

                case "dateAval":
                    let dateAvalObj = rentals.value as! [String : AnyObject]
                    self.rentalsObject.dateAval = dateAvalObj
                case "location":
                    let locationObj = rentals.value as! [String : AnyObject]
                    self.rentalsObject.location = locationObj

                case "price" :
                    let priceObj = rentals.value as! [String : AnyObject]
                    self.rentalsObject.price = priceObj

                case "bond" :
                    let bondObj = rentals.value as! [String: AnyObject]
                    self.rentalsObject.bond = bondObj

                case "pets" :
                    let petsObj = rentals.value as! [String: AnyObject]
                    self.rentalsObject.pets = petsObj

                case "description":
                    let desObj = rentals.value as! [String: AnyObject]
                    self.rentalsObject.descripton = desObj

                default:
                    break

                

            
            self.tableView.reloadData()
        )

    


【问题讨论】:

【参考方案1】:

使用 .childAdded 代替 .value。 ChildAdded 获取每个对象,而 Value 获取所有对象。您应该从 'cellForRowAr' 方法中删除 for 循环。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
       let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")

       cell.textLabel?.text = ("Title: \(String(describing: arrayOfTitles[indexPath.row]!)), Bond: \(String(describing: arrayOfBond[indexPath.row]!))")

       return cell




override func viewDidLoad() 
   super.viewDidLoad()

   databaseRef = Database.database().reference().child("Rentals")
   databaseRef?.observe(.childAdded, with:  (snapshot) in

       if let dictionary = snapshot.value as? [String: AnyObject] 

          switch snapshot.key 

             case "title" :
             _ = dictionary.mapself.arrayOfTitles.append($0.value as? String)
             case "rentalType":

             case "dateAval":

             case "location":

             case "price" :

             case "bond" :
             _ = dictionary.mapself.arrayOfBond.append($0.value as? String)
             case "pets" :

             case "description":

             default:
                break
           
        
     )
     self.tableView.reloadData()

【讨论】:

嗨 a.afanasiev,我现在设法让它工作,但我之前的代码遇到了与以前相同的问题。数组的输出似乎在做一些奇怪的事情,导致它们彼此错位。为了便于阅读,我在下面的另一个问题中发布了我的代码。 嗨 a.afanasiev,我现在设法让它工作,但我之前的代码遇到了与以前相同的问题。数组的输出似乎在做一些奇怪的事情,导致它们彼此错位。如果我从 ViewDidLoad 函数中打印数组,它们看起来是正确的 - 但是,如果我将它们输出到标签或从 cellForRowAt 函数中打印,则数组看起来是重复的。关于为什么会发生这种情况的任何想法? 你在“numberOfRowsInSection”方法中返回什么? RentalsObject.title.count 还是 arrayOfTitles.count? 我返回 arrayOfTitles.count 就好像我返回了 rents.Object.title.count 然后 CellForRowAt 函数似乎根本没有被调用,我在表格视图中什么也没有得到?

以上是关于Firebase/Swift - 从 Firebase 输出数据出错的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Firebase (Swift) 中删除一个孩子

从 Firebase Auto Id 中检索数据 - Firebase Swift

从 FIRRemoteConfigValue 转换为不相关的字符串类型总是失败:Firebase、Swift

从 firebase Swift 加载聊天

下载图像,然后从 Firebase Swift 3 缓存它

试图从 firebase Swift 获取数据