无法从Firestore数据库集合将数据加载到UITableView

时间:2020-05-25 21:43:23

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

我正在使用Firestore数据库和Swift。
我有用户集合和任务的一般集合。每个用户都有自己的任务集合。当用户注册时,我将任务从常规任务集合复制到用户自己的任务集合。

我的Firestore数据库层次结构如下所示:
任务-> firstBundle->任务
用户->用户ID->任务

目前一切正常。然后,我要将数据从用户的任务集合加载到UITableView。当我手动将任务添加到用户的任务集合时,数据将显示在表视图中。但是,当我将数据从常规任务集合复制到用户的任务集合时,该数据根本不会显示在表视图中。

  class TasksListScreen: UIViewController {

    var db = Firestore.firestore()
    var tasksArray = [Task]()

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        addTasks()
        loadData()
    }

手动将数据添加到用户的任务集合中并且可以正常工作(数据已添加到数据库中,并且任务数据显示在表视图中):

    // push tasks to the db
    func addTasks() {

        let userID = Auth.auth().currentUser!.uid
        let userTasksCollRef = db.collection("users").document(userID).collection("tasks")

        userTasksCollRef.addDocument(data: [
            "title": "Копійка гривню береже",
            "description": "Копійка гривню береже, чули таке? Чи є у Вас скарбничка? Якщо немає - є ідея. Спробуйте створити скарбничку своїми руками. Яка вона буде - справа Ваша. І ще, порада, заповніть ії.",
            "tip": "Живеться, якщо копійка ведеться",
            "hashtags": "#гроші #збереження #своїми руками"
        ])

        userTasksCollRef.addDocument(data: [
            "title": "В здоровому тілі - здоровий дух",
            "description": "Зробіть ранкову зарядку або пробіжку на свіжому повітрі.",
            "tip": "Фізична активність значно покращує самопочуття на цілий день",
            "hashtags": "#розвиток #фізична активність #здоров'я"
        ])
     }

将数据从常规任务集合(在数据库端手动填充之前填充)复制到用户的任务集合,并将复制的数据添加到tableview。
数据被复制并显示在Firestore数据库中用户的任务集中,但未加载到表视图中。

    // push tasks to the db
    func addTasks() {

        // copy from db.collection("tasks").document("firstBundle").collection("tasks") = tasksFirstBundleCollRef
        // to db.collection("users").document(userID) = userRef

        let userID = Auth.auth().currentUser!.uid
        let userRef = db.collection("users").document(userID)
        let tasksFirstBundleCollRef = db.collection("tasks").document("firstBundle").collection("tasks")

        tasksFirstBundleCollRef.getDocuments { (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err.localizedDescription)")
            } else {
                if let snapshot = querySnapshot {
                    for document in snapshot.documents {
                        let data = document.data()
                        let batch = self.db.batch()
                        let docset = querySnapshot

                        let newCollRef = userRef.collection("tasks").document()

                        docset?.documents.forEach {_ in batch.setData(data, forDocument: newCollRef)}

                        batch.commit(completion: { (error) in
                            if let error = error {
                                print(error.localizedDescription)
                            } else {
                                print("Successfully copied doc")
                            }
                        })
                    }
                }
            }
        }
    }

这是我将数据从数据库加载到表视图的方法:

    // load data to the table view from the db
    func loadData() {
        let userID = Auth.auth().currentUser!.uid
        let userTasksCollRef = db.collection("users").document(userID).collection("tasks")

        userTasksCollRef.getDocuments { (queryShapshot, error) in
            if let error = error {
                print("Error loading data: \(error.localizedDescription)")
            } else {
                self.tasksArray = queryShapshot!.documents.compactMap({Task(dictionary: $0.data())})
                print("Data: \(self.tasksArray)") 
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
            }
        }
    }

我的任务文件:

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

struct Task {
    var title: String
    var description: String
    var tip: String
    var hashtags: String

    var dictionary:[String:Any] {
        return [
            "title": title,
            "description": description,
            "tip": tip,
            "hashtags": hashtags
        ]
    }
}

extension Task : DocumentSerializable {
    init?(dictionary: [String : Any]) {
        guard let title = dictionary["title"] as? String,
            let description = dictionary["description"] as? String,
            let tip = dictionary["tip"] as? String,
            let hashtags = dictionary["hashtags"] as? String else {return nil}

        self.init(title: title, description: description, tip: tip, hashtags: hashtags)
    }
}

1 个答案:

答案 0 :(得分:0)

将以下内容添加到任务文件中:

class func parseData(snapshot: QuerySnapshot?) -> [Post] {
    var tasks = [Task]()

    guard let snap = snapshot else { return posts }
    for document in snap.documents {
        let data = document.data()
        let title = data["title"] as? String ?? ""
        let description = data["description"] as? String ?? ""
        let tip = data["tip"] as? [String] as? String ?? ""
        let hashtags = data["hashtags"] as? String ?? ""

        let task = Task(title: title, description: description, tip: tip, hashtags: hashtags)
        tasks.append(task)
    }

    return tasks
}

然后尝试使用以下内容加载表:

userTasksCollRef.getDocuments { (sapshot, error) in
    guard let snapshot = snapshot else {
       print("Error retrieving documents: \(error.debugDescription)")
       return
    }
    let task = Task.parseData(snapshot: snapshot)
    for task in tasks {
       self.tasksArray.append(task)
    }
    self.tableView.reloadData()
}