Swift 更新firebase中的数据

Swift 更新firebase中的数据,swift,firebase,google-cloud-firestore,Swift,Firebase,Google Cloud Firestore,我正在尝试使用包含firebase代码的小应用程序来了解更多信息。所以在这里,我制作了一个待办事项列表应用程序,我可以将任务添加到firebase,也可以将其删除,我遇到的问题是更新任务的状态(isComplete:Bool),我不知道如何编写firebase代码来更新数据。我读的几乎所有教程都是关于上传到实时数据库的数据的,我正在使用云,所以我想不出来。在这里,我写了这段代码,所以当任务完成后,我选择了单元格,圆圈变成了checkmark.circle,这是工作,但数据库当然不会更新

我正在尝试使用包含firebase代码的小应用程序来了解更多信息。所以在这里,我制作了一个待办事项列表应用程序,我可以将任务添加到firebase,也可以将其删除,我遇到的问题是更新任务的状态(isComplete:Bool),我不知道如何编写firebase代码来更新数据。我读的几乎所有教程都是关于上传到实时数据库的数据的,我正在使用云,所以我想不出来。在这里,我写了这段代码,所以当任务完成后,我选择了单元格,圆圈变成了checkmark.circle,这是工作,但数据库当然不会更新

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let cell = tableView.cellForRow(at: indexPath) as! TodoCell

        if cell.isComplete == false{
           cell.doneButton.image = UIImage(systemName: "checkmark.circle")
           cell.isComplete = true
  
       } else {
           cell.doneButton.image = UIImage(systemName: "circle")
           cell.isComplete = false

}
}
}
向firebase代码添加任务

    public func postTask(task:String, isComplete: Bool,
                            completion: @escaping (Result<Bool, Error>) -> ()) {
      guard let user = Auth.auth().currentUser else {
          return
      }
  
        let documentRef = db.collection(DatabaseService.itemsCollection).document()

        db.collection(DatabaseService.usersCollection).document(user.uid).
        collection(DatabaseService.tasksCollection).
        document(documentRef.documentID).setData(["task" : task,
                                                  "isComplete": isComplete,
                                                  "taskId": documentRef.documentID])
        { (error) in


        if let error = error {
          completion(.failure(error))
        } else {
          completion(.success(true))
        }
      }
    }
    
根据@bkbkchoy的回答,我写了以下代码:

func updateTask(task: TasksList,
                isComplete: Bool,
                        completion: @escaping (Result<Bool, Error>) -> ()) {
  guard let user = Auth.auth().currentUser else { return }

    db.collection(DatabaseService.usersCollection).document(user.uid)
   .collection(DatabaseService.tasksCollection).document(task.taskId)
   .updateData(["isComplete": isComplete]) { (error) in
          if let error = error {
            completion(.failure(error))
          } else {
            completion(.success(true))
    }
  }
}
    
}

但我有一个错误:

没有要更新的文档:项目/todo列表/数据库/(默认)/文档/users/jYZmghQeXodeF2/tasks/1

struct TasksList {
  let task: String
  let taskId: String
  let isComplete: Bool


}

extension TasksList {
  init(_ dictionary: [String: Any]) {
    self.task = dictionary["task"] as? String ?? ""
    self.taskId = dictionary["taskId"] as? String ?? ""
    self.isComplete = dictionary["isComplete"] as? Bool ?? false
  }
}

在Cloud Firestore中更新文档有几种方法:

  • 使用
    setData
    重写特定属性:
  • db.collection(DatabaseService.userscolection)
    .document(user.uid)
    .collection(DatabaseService.tasksCollection)
    .document(task.taskId)
    
    .setData([“isComplete”:isComplete],merge:true)
    您的方法无法工作

    单元格只是视图,它显示UI元素及其值,数据源是模型
    任务列表
    (为什么不简单地
    任务

    单元格被重用,当用户滚动时,您将丢失单元格中的
    isCompleted
    信息。您必须更新模型并重新加载视图

    首先,将模型声明为
    任务
    isComplete
    声明为
    var
    可执行。根据命名指南,
    任务
    应为
    名称
    标题
    任务id
    应为
    id

    struct Task {
      let task: String
      let taskId: String
      var isComplete: Bool
    }
    

    cellForRow
    中,根据模型设置单元格中的UI元素

    let task = todoItems[indexPath.row]
    let imageName = task.isComplete ? "checkmark.circle" : "circle"
    cell.doneButton.image = UIImage(systemName: imageName)
    cell.doneButton.tintColor = task.isComplete ? .systemBlue : .systemGray
    
    在模型中的
    didSelect
    切换
    isComplete
    ,重新加载行并保存任务

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
        todoItems[indexPath.row].isComplete.toggle()
        tableView.reloadRows(at: [indexPath], with: .none)
        let task = todoItems[indexPath.row]
        updateTask(task: task, isComplete: task.isComplete) { result in print(result) }
    }
    

    整个任务移交后,
    updateTask

    中不需要第二个参数
    isComplete
    I根据您的答案编写的代码更新了我的问题,我得到的错误请检查。您得到的错误表明文档尚未在该路径上创建。如果您想进行更新,并且不确定文档是否存在,则更安全的方法是使用选项1和
    setData merge:true
    route。使用setData,如果文档不存在,它将创建一个文档;如果文档已经存在,它将合并它(当设置合并标志时)。只有在确信文档存在或将抛出错误时,才应使用update。谢谢..文档存在,但我已找出错误的原因。:)哦,很高兴你解决了!问题是什么?task:TasksList当我在didSelectAtRow下使用它时,我得到了一个错误,我不能使用TasksList,我应该使用value insted,所以我写了变量var task2=TaskList(task:,taskId:,isComplete:false),
    TasksList
    包含什么(为什么不简单地说
    task
    ,一个实例代表一个任务)?@vadian我用答案更新了我的问题
    let task = todoItems[indexPath.row]
    let imageName = task.isComplete ? "checkmark.circle" : "circle"
    cell.doneButton.image = UIImage(systemName: imageName)
    cell.doneButton.tintColor = task.isComplete ? .systemBlue : .systemGray
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
        todoItems[indexPath.row].isComplete.toggle()
        tableView.reloadRows(at: [indexPath], with: .none)
        let task = todoItems[indexPath.row]
        updateTask(task: task, isComplete: task.isComplete) { result in print(result) }
    }