首页 > 解决方案 > 如果它们已经存在于 Swift iOS 中,如何从数组中删除 Firestore 文档

问题描述

我想删除类型数组中的重复文档,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 {
                
        }
    }

标签: iosarraysswiftfirebasegoogle-cloud-firestore

解决方案


关于主要问题(您如何判断文件是否存在),这可能取决于您对“存在”的资格是什么。

例如,如果你的意思是“数组是否已经有一个相同的元素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]通过手动转换/转换,您正在做很多额外的工作。并且,它会导致潜在的拼写错误/不一致/错误(例如,为什么模型中的每个属性都使用小写字母,除了ShopProfileImgand ShopHeaderImg?我会继续阅读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. 小心使用!强制解包 - 如果它失败,这会使你的应用程序崩溃

推荐阅读