【问题标题】:How to populate cells with field names from different documents?如何使用来自不同文档的字段名称填充单元格?
【发布时间】:2021-05-07 05:05:19
【问题描述】:

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

当学校用户创建一个事件时,它会使用 school_id 字段创建并放入该子集合中。我想要做的是在学生用户的表视图控制器中显示由具有相同 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 tableview 方法中调用完成处理程序。

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
}

这些都没有工作,我只是有一堆错误。回顾一下,基本上我想要做的是用他们具有匹配 ID 的学校的事件名称填充 Student TableVC 中的单元格。将添加一些额外的照片以进行更多说明。

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

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

【问题讨论】:

  • 如果子集合名称在主集合中的所有文档中完全相同,会影响查询吗?

标签: swift google-cloud-platform google-cloud-firestore completionhandler querying


【解决方案1】:

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

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

它是这样开始的。

   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

它工作得非常好。这是我的解决方案,我感到无比自豪。

【讨论】:

    猜你喜欢
    • 2021-12-29
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多