【问题标题】:How to remove Firestore documents from an array if they already exists in Swift iOS如果它们已经存在于 Swift iOS 中,如何从数组中删除 Firestore 文档
【发布时间】:2021-07-24 21:31:36
【问题描述】:

我想删除 addShops 类型数组中的重复文档,这是我创建的自定义对象,用于添加我的文档并稍后在 tableView 中查看它们。

我想知道如何检查数组中是否已经存在 Firestore 文档?

我在 swift 和 iOS 开发方面处于中级水平,所以我仍然不了解数组和 Firebase Firestore 方面的任何高级知识。

所以,我将不胜感激。

这是我的代码:

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

struct addShop {
    
    var shopPID:String
    var name:String
    var location:String
    var numTables:String
    var traffic:String
    var indoor:Bool
    var outdoor:Bool
    var drivethru:Bool
    var takeaway:Bool
    //images URL
    var shopProfileImage:String
    var shopHeaderImage:String
    //true or false
    var sponsered:Bool
    //Numbers
    var ratings:Float
    var contactNumber:String
    
    
    var dictionary:[String:Any]
    {
        return [
            "shopPID":shopPID,
            "name":name,
            "location":location,
            "numTables":numTables,
            "traffic":traffic,
            "indoor":indoor,
            "outdoor":outdoor,
            "drivethru":drivethru,
            "takeaway":takeaway,
            "ShopProfileImg":shopProfileImage,
            "ShopHeaderImg":shopHeaderImage,
            "sponsered":sponsered,
            "ratings":ratings,
            "contactNumber":contactNumber
        ]
    }
    
}

extension addShop : DocumentSerializable {
    
    init?(dictionary:[String:Any]) {
        
        guard let shopPID = dictionary["shopPID"] as? String,
            let name = dictionary["name"] as? String,
            let location = dictionary["location"] as? String,
            let numTables = dictionary["numTables"] as? String,
            let traffic = dictionary["traffic"] as? String,
            let indoor = dictionary["indoor"] as? Bool,
            let outdoor = dictionary["outdoor"] as? Bool,
            let drivethru = dictionary["drivethru"] as? Bool,
            let takeaway = dictionary["takeaway"] as? Bool,
            let shopProfileImage = dictionary["ShopProfileImg"] as? String,
            let shopHeaderImage = dictionary["ShopHeaderImg"] as? String,
            let sponsered = dictionary["sponsered"] as? Bool,
            let ratings = dictionary["ratings"] as? Float,
            let contactNumber = dictionary["contactNumber"] as? String
            else {return nil}
        self.init(shopPID: shopPID, name: name, location: location, numTables: numTables,traffic: traffic,indoor:indoor,outdoor:outdoor,drivethru:drivethru,takeaway:takeaway ,shopProfileImage: shopProfileImage,shopHeaderImage: shopHeaderImage,sponsered: sponsered, ratings: ratings,contactNumber:contactNumber)
    }
}

我要检查数组中文档的 Firestore 代码:

  func getNextShops() {
    
        if self.lastDoc != self.firestoreLastDocument{
      
            db.collection("Shops").order(by: "__name__").start(afterDocument: lastDoc!).limit(to: 8).getDocuments(){ docs, err in
                self.docsCount = docs?.count
                if  self.docsCount == 0{
                    self.tableView.stopLoading()
                    return
                }else{
                if let err = err {
                    print(err.localizedDescription)
                }else{
                        docs?.documents.forEach{ data in
                            
                            //here i want to check if the document already exists,
                            //if it exists do not append it again to the array.
                           
                                self.shops.append(addShop(dictionary: data.data())!)
                                DispatchQueue.main.async {
                                    self.tableView.reloadData()
                                    
                                }
                        }
                    self.lastDoc = docs?.documents[(docs?.documents.endIndex)! - 1]
                    self.lastDocID = self.lastDoc?.documentID
            
                    }
                }
            }
            } else {
                
        }
    }

【问题讨论】:

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


    【解决方案1】:

    关于主要问题(您如何判断文档是否存在),这可能取决于您对“存在”的限定。

    例如,如果你的意思是“数组是否已经有一个元素具有相同的shopPID,你可以这样做:

    guard let shopPID = document.get("shopPID") as? String,
        !self.shops.contains { $0.shopPID == shopPID }
      else {
           return
    }
    

    如果你想检查完全相等,你需要确保你的模型符合Equatable,然后你可以这样做:

    guard let newShop = addShop(dictionary: data.data()) else {
      return
    }
    if !self.shops.contains(newShop) {
      //add it to the array
    }
    

    您可能还需要考虑在代码中清理一些其他内容:

    1. 在 Swift 中,类型通常以大写字母开头。至少,addShop 应该是AddShop。而且,真的,它应该只是Shop

    2. 手动转换为[String:Any] 或从[String:Any] 转换为您做了大量额外的工作。并且,它会导致潜在的拼写错误/不一致/错误(例如,为什么模型中的每个属性都使用小写字母,ShopProfileImgShopHeaderImg 除外?我会在 Codable 上做一些阅读,然后查看Firebase 文档中关于使用自定义对象的这一部分:https://firebase.google.com/docs/firestore/query-data/get-data#custom_objects

    这是一篇关于 Codable 和 Firestore 的相当广泛的文章:https://peterfriese.dev/firestore-codable-the-comprehensive-guide/

    1. 谨防使用! 强制展开 - 如果失败,这会使您的应用崩溃

    【讨论】:

    • 使用它的当前名称,你可以通过struct addShop : Equatable {开始声明类型
    • 哇,答案太棒了。我已经在这个问题上工作了一个多星期,每天至少 4 个小时,但没有找到解决方案。今天我想到了这种数组方法来首先检查文档是否存在,但我不知道如何实现它。谢谢先生,您的代码将帮助我越来越多地改进 iOS 开发。非常感谢!!!!!!
    猜你喜欢
    • 1970-01-01
    • 2011-01-18
    • 2021-12-02
    • 2011-05-19
    • 1970-01-01
    • 2016-07-16
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多