如何使用来自不同文档的字段名称填充单元格?

How to populate cells with field names from different documents?

对于集合“school_users”中的每个文档,我都有一个名为 events 的子集合。

当学校用户创建事件时,它是使用 school_id 字段创建的并放入该子集合中。我想要做的是在学生用户的 table 视图控制器中显示事件,这些事件是由学校使用相同 ID 创建的(学生用户的学生 ID 与学校 ID 匹配)。

我不确定该怎么做,所以我尝试了一些东西。

    func getStudentID(completion: @escaping ((String?) -> ())) {
    db.collection("student_users").whereField("userID", isEqualTo: user!.uid).getDocuments { (querySnapshot, err) in
        if let err = err {
            print("There was an error fetching the documents: \(err)")
        } else {
            self.studID = querySnapshot!.documents.map { document in
                return StudentID(studentID: (document.get("school_id") as! String))
            }
            
            let fixedID = "\(self.studID)"
            let substring = fixedID.dropFirst(30).dropLast(3)
            let realString = String(substring)
            completion(realString)
            
        }
    }
}

我根据从上次尝试获取字符串形式的学生 ID 的问题中学到的知识创建了一个函数。

但在此之前,我在没有完成处理程序的情况下使用上面的相同函数并返回一个字符串并尝试将其输入到查询中。显然这行不通,但我还是尝试了。

   //MARK: - Needs to be fixed
func getSchoolID() {
    db.collectionGroup("events").whereField("school_id", isEqualTo: getStudentID()).getDocuments { (querySnapshot, error) in
        if let error = error {
            print("There was an error fetching the events: \(error)")
        } else {
            self.events = querySnapshot!.documents.map { document in
                return EventName(eventName: (document.get("event_name") as? String) ?? "")
            }
            self.tableView.reloadData()
        }

    }
}

所以我尝试的最后一件事是在 cellForRowAt table 视图方法中调用完成处理程序。

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let cell = tableView.dequeueReusableCell(withIdentifier: Constants.CellDetails.cellName, for: indexPath)
    
  getStudentID { [weak self] (realString) in
   
        cell.textLabel?.text = self?.events[indexPath.row].eventName

    }
    
    cell.textLabel?.font = UIFont(name: Constants.CellDetails.fontName, size: 22)

    return cell
}

None 其中的一些最终可以正常工作,我只是遇到了一堆错误。回顾一下,基本上我想要做的是用具有匹配 ID 的学校的事件名称填充 Student TableVC 中的单元格。将添加一些额外的照片以进行更多说明。

所以这些是由 Santa Fe High School 管理员用户创建的事件,我希望它们显示在 Santa Fe Highschool 学生用户的table视图中。

这是 VC 如果学校 ID 匹配,我希望他们出现。登录的用户确实具有与 Santa Fe High 相同的 ID,因此我希望他们显示,但这是我无法弄清楚的。希望你明白我想做什么。欢迎提出更多问题。

这适用于遇到同样问题的任何人

基本上我所做的就是将整个查询放入完成处理程序中。

事情是这样开始的。

   func getStudentID(completion: @escaping ((String?) -> ())) {
    db.collection("student_users").whereField("userID", isEqualTo: user!.uid).getDocuments { (querySnapshot, err) in
        if let err = err {
            print("There was an error fetching the documents: \(err)")
        } else {
            self.studID = querySnapshot!.documents.map { document in
                return StudentID(studentID: (document.get("school_id") as! String))
            }
            
            let fixedID = "\(self.studID)"
            let substring = fixedID.dropFirst(30).dropLast(3)
            let realString = String(substring)
            completion(realString)
            
        }
    }
}

此处的此函数以我需要的字符串格式获取学生 ID,因此我可以将其放入查询中。

如您所见,它是一个完成处理函数。我知道我需要那个确切的值并且知道我不能只在查询调用的 isEqualTo: 参数中执行它,所以我决定通过在 viewDidLoad() 中抛出一个打印语句来测试该函数.我很高兴看到它出现在控制台上。所以我意识到为什么不做我在这件事上做的同样的事情:

getStudentID { (studentID) in
        if let id = studentID {
            print(id)
        }
    }

而是让 id 常量成为查询调用的 isEqualTo: 参数中的值。

这导致我这样做...

func getSchoolID() -> String {
    
    getStudentID { (studentID) in
        if let idForStudent = studentID {
            self.db.collectionGroup("events").whereField("school_id", isEqualTo: idForStudent).getDocuments { (querySnapshot, error) in
                if let error = error {
                    print("There was an error fetching the events: \(error)")
                } else {
                    self.events = querySnapshot!.documents.map { document in
                        return EventName(eventName: (document.get("event_name") as? String) ?? "")
                    }
                    self.tableView.reloadData()
                }

            }
        }
    }
    
    return "\(events)"
}

这最终完美地工作了,我记得无数次对自己重复我的天啊。这是我最喜欢的编码部分,解决了那个大问题。

最后,为了填充单元格,我所要做的就是编写这行代码

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

而且效果非常好。这是我的解决方案,我无比自豪。