Swift Firestore-删除表格单元格并从Firestore中删除文档 [英] Swift Firestore - Delete Table Cell and Remove Document from Firestore

查看:57
本文介绍了Swift Firestore-删除表格单元格并从Firestore中删除文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Swift开发一个育儿应用程序,正在使用Firebase Cloud Firestore为我的Swift应用程序保存数据.应用程序的一部分是父母可以在其中添加孩子并在应用程序中显示的地方.

I am developing a parenting app in Swift, I am using Firebase Cloud Firestore to save data for my Swift App. A part of the app is where Parents can add their children and display them in the app.

我创建了一个子模型,用于在向表视图中添加新子模型时使用.

I have created a child model which I use when adding a new child to my tableview.

子模型

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

// Child Struct
struct Child {

    var name: String
    var age: Int
    var timestamp: Date
    var imageURL: String

    var dictionary:[String:Any] {
        return [
            "name":name,
            "age":age,
            "timestamp":timestamp,
            "imageURL":imageURL
        ]
    }

}

//Child Extension
extension Child : DocumentSerializable {
    init?(dictionary: [String : Any]) {
        guard let  name = dictionary["name"] as? String,
            let age = dictionary["age"] as? Int,
            let  imageURL = dictionary["imageURL"] as? String,
            let timestamp = dictionary["timestamp"] as? Date else {
                return nil
        }
        self.init(name: name, age: age, timestamp: timestamp, imageURL: imageURL)
    }
}

我通过在视图中运行确实加载了loadData()的函数,将数据添加到应用程序的tableview中

I add data to my tableview in my app by running a function in my view did load, loadData()

我首先在此上方设置了2个变量:

I set 2 variables above this first:

//firestore connection
var db:Firestore!

//child array
var childArray = [Child]()

viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()

    //Connect to database
    db = Firestore.firestore()

    // call load data function
    loadData()
    checkForUpdates()

}

loadData()函数连接到已登录的用户数据,然后抓取用户的子级"文档,并使用子级对象"协议将子级添加到childArray中.

The loadData() Function connects to the logged in users data, then grabs that users 'children' documents and adds the children to the childArray using the Child Object protocol.

func loadData() {
        // create ref to generate a document ID
        let user = Auth.auth().currentUser
        db.collection("users").document((user?.uid)!).collection("children").getDocuments() {
            QuerySnapshot, error in
            if let error = error {
                print("\(error.localizedDescription)")
            } else {
                // get all children into an array
                self.childArray = QuerySnapshot!.documents.flatMap({Child(dictionary: $0.data())})
                DispatchQueue.main.async {
                    self.childrenTableView.reloadData()
                }
            }
        }
    }

我通过返回childArray计数来获得numberOfRowsInSection:

I get the numberOfRowsInSection by returning the childArray count like so:

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

我使用自定义单元格类并使用childArray内容填充cellForRow,如下所示:

I populate the cellForRow using a custom cell class and using the childArray contents like so:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       let cell = childrenTableView.dequeueReusableCell(withIdentifier: "Cell") as! ChildCellTableViewCell
        let child = childArray[indexPath.row]

        cell.childNameLabel.text = "\(child.name)"
        cell.childAgeLabel.text =  "Age: \(child.age)"

        let url = URL(string: "\(child.imageURL)")
        cell.childImage.kf.setImage(with: url)

        cell.childNameLabel.textColor = UIColor.white
        cell.childAgeLabel.textColor = UIColor.white
        cell.backgroundColor = UIColor.clear

        return cell
    }

我希望能够滑动以删除每个表格行单元格,因此我实现了以下内容:

I want to be able to swipe to delete each table row cell so I have implemented the following:

 func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == UITableViewCellEditingStyle.delete) {

            childArray.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)

        }
    }

此操作成功从应用程序中删除了该行.但是我的问题是我不确定如何获取已删除的行以从Firestore数据库中删除匹配的数据.

This successfully removes the row from the app. But my problem is I am unsure how to get the deleted row to delete the matching data from the Firestore Database.

要使事情更加复杂,因为每个孩子都有一张图像,该图像存储在Firebase Storage中,因此我还需要以某种方式删除该图像.图片网址存储在子文档中的图片网址下.

And to complicate things even more, as each child has an image, which gets stored in Firebase Storage, I need to somehow also delete this image. The image URL is being stored in the childrens document under imageURL.

我将不胜感激,因为它为我提供了任何指导或朝着正确的方向发展,我找不到有关Firestore和UITableViews的大量文档,所以甚至不知道下一步该怎么做?

I would appreciate any guidance or pointing in the right direction for this, I cannot find much documentation with regards to Firestore and UITableViews so don't know what to even try next?

更新'canEditRow'函数中,我设法从删除的表行中从Firebase存储中删除了子映像,但是我正在努力从Firestore中删除子文档.我可以查询需要删除的文档,但不确定如何从此查询中运行delete()函数?

UPDATE In the 'canEditRow' Function I have managed to delete the childs image from Firebase storage from the table row I deleted, but I am struggling to delete the child document from Firestore. I can query the document I need to delete, but not sure how to run the delete() function from this query?

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == UITableViewCellEditingStyle.delete) {

            // 1. First Delete the childs image from storage
            let storage = Storage.storage()
            let childsImageURL = childArray[indexPath.row].imageURL
            let storageRef = storage.reference(forURL: childsImageURL)

            storageRef.delete { error in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    print("File deleted successfully")
                }
            }


            // 2. Now Delete the Child from the database
            let name = childArray[indexPath.row].name

            let user = Auth.auth().currentUser
            let query = db.collection("users").document((user?.uid)!).collection("children").whereField("name", isEqualTo: name)

            print(query)


            childArray.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)

        }
    }

推荐答案

我认为我已经设法解决了这个问题,而且似乎可行.现在,在'canEditRow'函数的编号2中,我可以找到特定的子项(在滑动表格单元格以进行删除时),它会在Firebase Firestore数据库中删除相同的子项.

I think I have managed to work this out, and it seems to be working. In the 'canEditRow' Function, number 2, I can now find the specific child (when swiping the table cell to delete) and it deletes the same one in Firebase Firestore Database.

我不确定这是否是正确的方法,或者是否缺少任何错误检查,但似乎一切正常.

I am not sure if this is the correct way of doing it, or if I am missing any error checking, but it all seems to be working.

如果任何人都可以在这里发现任何错误,请告诉我,我真的想确保它可以安全使用并且所有后备功能都已到位.

If anyone can spot any errors here please let me know, I really want to make sure it is safe to use and all fallbacks are in place.

这就是我为了使整个工作正常进行的工作.

So here is what I have done to make the whole thing work.

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == UITableViewCellEditingStyle.delete) {

            // 1. First Delete the childs image from storage
            let storage = Storage.storage()
            let childsImageURL = childArray[indexPath.row].imageURL
            let storageRef = storage.reference(forURL: childsImageURL)

            storageRef.delete { error in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    print("File deleted successfully")
                }
            }



            // 2. Now Delete the Child from the database
            let name = childArray[indexPath.row].name
            let user = Auth.auth().currentUser
            let collectionReference = db.collection("users").document((user?.uid)!).collection("children")
            let query : Query = collectionReference.whereField("name", isEqualTo: name)
            query.getDocuments(completion: { (snapshot, error) in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    for document in snapshot!.documents {
                        //print("\(document.documentID) => \(document.data())")
                        self.db.collection("users").document((user?.uid)!).collection("children").document("\(document.documentID)").delete()
                }
            }})


            // 3. Now remove from TableView
            childArray.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)

        }
    }

这篇关于Swift Firestore-删除表格单元格并从Firestore中删除文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆