【问题标题】:How to update field values in a document - Firebase如何更新文档中的字段值 - Firebase
【发布时间】:2020-10-23 07:58:21
【问题描述】:

我有一个名为 objects 的集合/Object 类型的文档,它有一个 ObjectNotification 类型的数组,我正在尝试将每个 notification.read 更新为 true

我有一个视图,它显示单个数组 self.viewModel.userNotifications 中所有对象的所有 userNotifications

onAppear 用于视图时,我尝试将self.viewModel.userNotifications 中的每个userNotification.read 设置为true 并更新FirestoreDB。

但是我不确定采用的最佳方法,目前我正在遍历数组并尝试更新 self.viewModel.objects.userNotifications 中的每个 userNotification,然后更新数据库中的文档,这将更新 self.viewModel.userNotifications,因为它会获取所有 @ 987654335@.

但是当我尝试更改结构时出现以下错误,我试图更改 for in 语句中的值,然后调用我的 updateObect(object) 方法来更新数据库中的文档。

不能通过下标赋值:'h' 是一个 'let' 常量

.onAppear() {
        // Mark as read
        let read = objectManager.markNotificationsAsRead(self.viewModel.userNotifications)
        self.viewModel.updateObjectNotifications(readNotifcations: read)
    }


func markNotificationsAsRead(_ notifications: [ObjectNotification]) -> [ObjectNotification]{
    
    // Mark notifications as read
    
    var readNotifications: [ObjectNotification] = []
    
    for n in notifications {
        if n.read == false {
            // Create new with true
            var new = n
            new.read = true
            readNotifications.append(new)
        }
    }
    
    // Return update notifications with read = true
    return readNotifications
}



func updateObjectNotifications(readNotifcations: [ObjectNotification]) {
    if let currentUser = Auth.auth().currentUser {
        for h in self.objects {
            for n in h.notifications {
                if n.deliveredTo == currentUser.email {
                    for r in readNotifcations {
                        if r.id == n.id {
                            // same notif for home
                            // h.notifications.rem
                             if let index = h.notifications.firstIndex(of: n) {
                                
                                h.notifications[index] = r // Cannot assign through subscript: 'h' is a 'let' constant
                                
                            }
                        }
                    }
                }
                // update object in db
            }
        }
    }
}

除了上面的方法,如何更改数据库中的字段?

【问题讨论】:

  • 请添加更多代码以使其成为minimal, reproducible example
  • 这个问题非常模糊和不完整。例如。你问的是for h in self.objects { 这一行,但我们不知道self.objects 是什么。我们也不知道您的任何 Classes 或 Structs 是什么样的 - 但是,如果您的 h 对象(无论是什么)的属性 .notifications 是 let 属性,它就无法更改。您能否阐明您实际尝试做什么(使用 Firebase)并添加有关您的模型外观的更多信息?

标签: swift firebase google-cloud-firestore


【解决方案1】:

这是针对实际问题的解决方案,并未解决问题的 Firebase 部分,因为实际问题中并未对此进行概述。

我将在这里大胆猜测,因为问题不完整,但我认为问题中的任何对象“h”都是包含通知数组属性的结构。

如果是这样,那么您不能在 for 循环中执行此操作

h.notifications[index] = r

因为结构是 value 类型,不像是 reference 类型的类。这意味着在 for 循环中,对象是数组元素的副本,而不是元素本身

for copyOfArrayElement in someArrayOfStructs {}

有几个解决方案;这里有两个。第一种是使用索引遍历数组以访问实际的结构对象。假设我们有一个带有名称和数组属性的水果结构数组

struct FruitStruct {
    var name = ""
    var someList = [String]()
}

var banana = FruitStruct(name: "banana", someList: ["a", "b", "c"])
var grape = FruitStruct(name: "grape", someList: ["d", "e", "f"])

var fruitsArray = [banana, grape]

然后循环将每个水果名称修改为“Hello”,并将 someList 中索引为 1 的元素修改为“World”

for i in 0..<fruitsArray.count {
    fruitsArray[i].name = "Hello"
    fruitsArray[i].someList[1] = "World"
}

fruitsArray.forEach { print($0.name, $0.someList) }

和输出

Hello ["a", "World", "c"]
Hello ["c", "World", "e"]

或者将结构更改为一个类(这是一个引用),这样您就可以使用现有的循环直接修改属性。

class FruitClass {
    var name = ""
    var someList = [String]()
    
    convenience init(withName: String, andArray: [String] ) {
        self.init()
        self.name = withName
        self.someList = andArray
    }
}

【讨论】:

    猜你喜欢
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多