Firestore数据库中的数据未显示在表视图中

时间:2020-06-01 18:51:52

标签: ios swift xcode firebase google-cloud-firestore

我正在使用Swift和Firestore数据库来实现Twitter之类的应用。
单击按钮到数据库时,我想添加甜味(就像推特一样)。然后在表格视图中显示它。 数据已添加到数据库。但是不会显示在表格视图中。因此,当我运行一个应用程序时,我看到空的表视图。
请帮忙!

TableViewController文件:

import UIKit
import FirebaseFirestore
import Firebase

class TableViewController: UITableViewController {

    var db:Firestore!

    var sweetArray = [Sweet]()

    override func viewDidLoad() {
        super.viewDidLoad()

        db = Firestore.firestore()

        loadData()
    }

    func loadData() {
        db.collection("sweets").getDocuments() {
            querySnapshot, error in

            if let error = error {

                print("Error loading documents to the db: \(error.localizedDescription)")

            } else {

                self.sweetArray = querySnapshot!.documents.flatMap({Sweet(dictionary: $0.data())})

                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }

            }
        }
    }

    @IBAction func composeSweet(_ sender: Any) {

           let composeAlert = UIAlertController(title: "New Sweet", message: "Enter your name and message", preferredStyle: .alert)

           composeAlert.addTextField { (textField:UITextField) in
               textField.placeholder = "Your name"
           }

           composeAlert.addTextField { (textField:UITextField) in
               textField.placeholder = "Your message"
           }

           composeAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
           composeAlert.addAction(UIAlertAction(title: "Send", style: .default, handler: { (action:UIAlertAction) in

            if let name = composeAlert.textFields?.first?.text, let content = composeAlert.textFields?.last?.text {
                let newSweet = Sweet(name: name, content: content, timeStamp: Date())

                var ref:DocumentReference? = nil
                ref = self.db.collection("sweets").addDocument(data: newSweet.dictionary) {
                    error in

                    if let error = error {
                        print("Error adding document: \(error.localizedDescription)")
                    } else {
                        print("Document added with ID: \(ref!.documentID)")
                    }
                }
            }
           }))

           self.present(composeAlert, animated: true, completion: nil)

       }

       override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
       }

       override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
           return sweetArray.count
       }

       override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

        let sweet = sweetArray[indexPath.row]

        cell.textLabel?.text = "\(sweet.name) : \(sweet.content)"

        cell.detailTextLabel?.text = "\(sweet.timeStamp)"

        return cell
       }

}

甜文件:

import Foundation
import FirebaseFirestore

protocol DocumentSerializable {
    init?(dictionary:[String:Any])
}

struct Sweet {
    var name: String
    var content: String
    var timeStamp: Date

    var dictionary:[String:Any] {
        return [
            "name": name,
            "content": content,
            "timeStamp": timeStamp
        ]
    }
}

extension Sweet:DocumentSerializable {
    init?(dictionary: [String : Any]) {
        guard let name = dictionary["name"] as? String,
            let content = dictionary["content"] as? String,
            let timeStamp = dictionary["timeStamp"] as? Date else {return nil}

        self.init(name: name, content: content, timeStamp: timeStamp)
    }
}

我的故事板: enter image description here

我正在运行的应用程序:

2 个答案:

答案 0 :(得分:0)

似乎您在querySnapshot中有数据,但在sweetArray中为空,这意味着您只有一个正在解析并将接收的数据错误地映射到structs中。修改此行以解决您的问题:

self.sweetArray = querySnapshot!.documents.flatMap({Sweet(dictionary: $0.data())})

答案 1 :(得分:0)

我无法提供具体答案,但可以解释如何查找问题所在。

虽然添加保护语句来保护您的代码真是棒极了,但这也可能导致无法正确处理问题。

例如从您的问题中获取这段代码

guard let name = dictionary["name"] as? String,
            let content = dictionary["content"] as? String,
            let timeStamp = dictionary["timeStamp"] as? Date else {return nil}

正如您所看到的,如果名称,内容或时间戳存在问题,守卫会抓住它-但是,返回nil意味着它默默地失败,没有任何问题的迹象。

例如,假设一个字段名称被意外地命名为Name而不是name-好吧,这将失败,但是您永远不会知道它。

我建议单独处理字段以捕获特定问题。像这样

let name = dictionary["name"] as? String ?? "name field not found"
let name = dictionary["content"] as? String ?? "content field not found"
let name = dictionary["timesStamp"] as? Date ?? "timestamp field not found"

这称为nil合并,如果为nil,它将替代默认值。然后,通过检查传入的数据,您可以找到导致问题的文档。您也可以这样做

guard let name = dictionary["name"] as? String else { //handle the error }

无论哪种情况,您都可以获得有关故障性质的更多数据。

相关问题