首页 > 解决方案 > 如何使单元格文本标签成为 Firestore 集合中文档中的特定字段?

问题描述

所以我的目标是让我的仪表板中的表格视图单元格填充我的 Firestore 集合中文档的特定字段“event_name”。这是我使用 Firebase 文档提出的代码。

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: Constants.CellDetails.cellName, for: indexPath) as! SwipeTableViewCell
    cell.delegate = self
 
    db.collection("school_users").whereField("event_cost", isEqualTo: "Free")
        .getDocuments() { (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in querySnapshot!.documents {
                    cell.textLabel?.text = "\(document.data())"
                }
            }
    }
    

所以基本上,我期望发生的是代码会神奇地在单元格中填充字段名称,我知道这是不现实的。我将提供实际发生的情况的屏幕截图。

代码结果

所以是的,如果有人知道我可以对该字段进行非常具体的查询并能够在单元格中填充它的方法,那就太好了。谢谢。

标签: swiftfirebaseuitableviewgoogle-cloud-firestorequerying

解决方案


这里有几个问题。

首先是您在cellForRowAt. 虽然这在技术上是可行的,但它会为桌子上的每个单元格触发,并且效率非常低。您应该将该 API 调用移动到您可以更好地控制其发生位置的其他地方(viewDidLoad可能是最基本的示例),然后存储结果,以便您以后可以从cellForRowAt

一次,您执行了查询,document.data()返回 a[String:Any]以便您可以通过执行以下操作来选择一个字段:

let eventName = document.data()["event_name"]

或者你可以使用document.get("event_name")

您可能只想存储名称,或者更好的是,存储代表事件的对象以及某处的所有字段(又名 var events : [Event]),然后您可以cellForRowAt通过执行以下操作来填充您的单元格:

cell.textLabel?.text = events[indexPath.row].eventName

在 Firebase 文档中有更多关于从 Firebase 获取数据并将该数据转换为对象的文档:https ://firebase.google.com/docs/firestore/query-data/get-data

其中一些可能看起来像的(未经测试的)样本。在现实生活中,您会想要处理错误,而不是强制打开任何东西等。

struct Event {
    var eventName : String
}

class FBViewController : UITableViewController {
    var events = [Event]()
    
    override func viewDidLoad() {
        db.collection("school_users").whereField("event_cost", isEqualTo: "Free")
                .getDocuments() { (querySnapshot, err) in
                    if let err = err {
                        print("Error getting documents: \(err)")
                    } else {
                        self.events = querySnapshot!.documents.map { document in
                            return Event(eventName: (document.get("event_name") as? String) ?? "")
                        }
                        self.tableView.reloadData()
                    }
            }
    }
    
//Other table view functions....

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: Constants.CellDetails.cellName, for: indexPath) as! SwipeTableViewCell
        cell.textLabel?.text = events[indexPath.row].eventName
    }
}

推荐阅读