【问题标题】:Removing an array item from Firestore从 Firestore 中删除数组项
【发布时间】:2021-08-14 19:58:53
【问题描述】:

我花了几天时间研究这个问题,包括各种答案,例如:Firebase Firestore: Append/Remove items from document array 但无法弄清楚如何真正让它发挥作用。

我有两个结构:

struct TestList : Codable {
    var title : String
    var color: String
    var number: Int
}

struct TestGroup: Codable {
    var items: [TestList]
}

我可以使用FieldValue.arrayUnion添加数据:

@objc func addNewItem() {
        
        let testList = TestList(title: "Testing", color: "blue", number: Int.random(in: 1..<999))
        let docRef = FirestoreReferenceManager.simTest.document("abc")
        docRef.updateData([
            "items" : FieldValue.arrayUnion([["title":testList.title,
                                             "color":testList.color,
                                             "number":testList.number]])
        ])
    }

上述工作如在 Firestore 仪表板中所反映的那样:

但是,如果我尝试删除数组中的一项,它就是行不通的。

@objc func removeItem() {
 let docRef = FirestoreReferenceManager.simTest.document("abc")
        docRef.getDocument { (document, error) in
            do {
                let retrievedTestGroup = try document?.data(as: TestGroup.self)
                let retrievedTestItem = retrievedTestGroup?.items[1]
                guard let itemToRemove = retrievedTestItem else { return }
                docRef.updateData([
                    "items" : FieldValue.arrayUnion([["title" : itemToRemove.title,
                                                      "color" : itemToRemove.color,
                                                      "number" : itemToRemove.number]])
                ]) { error in
                    if let error = error {
                    print("error: \(error)")
                } else {
                    print("successfully deleted")
                }
                }

            } catch {

            }
        }
}

我已将itemToRemove 打印到日志中以检查它是否正确。但它只是不会将其从 Firestore 中删除。没有返回错误,但 "successfully deleted" 已记录。

请注意,上面是测试代码,因为我已经简化了我实际需要的测试代码,因为我无法让它工作。

关于我在这里做错了什么有什么想法吗?

【问题讨论】:

    标签: swift google-cloud-firestore


    【解决方案1】:

    您必须使用arrayRemove 从数组中删除项目。

    @objc func removeItem() {
        let docRef = FirestoreReferenceManager.simTest.document("abc")
        
        docRef.getDocument { (document, error) in
            do {
                let retrievedTestGroup = try document?.data(as: TestGroup.self)
                let retrievedTestItem = retrievedTestGroup?.items[1]
                guard let itemToRemove = retrievedTestItem else { return }
                docRef.updateData([
                    "items" : FieldValue.arrayRemove([["title" : itemToRemove.title,
                                                      "color" : itemToRemove.color,
                                                      "number" : itemToRemove.number]])
                ]) { error in
                    if let error = error {
                        print("error: \(error)")
                    } else {
                        print("successfully deleted")
                    }
                }
                
            } catch {
                
            }
        }
    }
    

    我遇到过这种简单的方法不起作用的情况,因为该项目是一个复杂的对象,在这种情况下,我首先必须从 Firestore 查询该项目并将该实例插入arrayRemove() 以将其删除。

    您的方法没有任何副作用的原因是 Firestore 中的数组与 Swift 中的数组不同,它们是数组和集合的混合体。您可以在 Firestore 中使用重复项初始化数组,但不能使用 arrayUnion() 将数组附加到重复项。尝试使用 arrayUnion() 附加重复项将静默失败,例如您的情况。

    【讨论】:

    • 谢谢。我实际上在这里遇到了剪切和粘贴错误。如果我明确列出每个字段值,这似乎有效,例如“title”,然后是其对应的值。这似乎是让它工作的唯一方法。我尝试在 FieldValue.arrayRemove 中使用 TestList 对象,但它似乎不喜欢那样
    • @Anthony 这不是唯一的方法。另一种方法是从 Firestore 获取项目(在事务中或事务中)并将其插入 arrayRemove()
    • 我在尝试使其正常工作时遇到问题,我将其恢复为上述内容。我会再试一次,如果我不能得到它,我会发布另一个问题。谢谢大家。
    • 找出问题发生的位置,以及结构/对象中存在日期属性的时间。我在stackoverflow.com/questions/67733560/… 发布了一个新问题,如果您有任何想法,我将不胜感激。
    猜你喜欢
    • 2021-04-03
    • 2019-10-03
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多