【问题标题】:Access childAutoID to update selected child value in Firebase访问 childAutoID 以更新 Firebase 中的选定子值
【发布时间】:2017-09-21 12:15:59
【问题描述】:

为了填充我的 tableView,我将项目(从结构创建)附加到本地数组:

func loadList() {
        var newAnnotations: [AnnotationListItem] = []
    if let uid = Auth.auth().currentUser?.uid {
        uidRef.child(uid).child("annotations").queryOrderedByKey().observeSingleEvent(of: .value, with: {snapshot in

            for item in snapshot.children {
                let annotationItem = AnnotationListItem(snapshot: item as! DataSnapshot)
                newAnnotations.append(annotationItem)
            }
            annotationList = newAnnotations
            self.tableView.reloadSections([0], with: .fade)
        })
    }
}

当我点击一个特定的行时,我被带到一个DetailViewController,它只是一个大的UITextView(命名注释)。显示的UITextView.text 基于选定的indexPath.row,并且从数组中检索“notes”值。现在用户可以输入一些文本,完成后,textViewDidEndEditing 函数被调用:

func textViewDidEndEditing(_ textView: UITextView) {
    notes.resignFirstResponder()
    navigationItem.rightBarButtonItem = nil

    let newNotes = self.notes.text
    print(newNotes!)
}

现在我想updateChildValuesnewNotes 到我的 JSON 中的子节点“notes”:

"users" : {
  "gI5dKGOX7NZ5UBqeTdtu30Ze9wG3" : {
    "annotations" : {
      "-KuWIRBARv7osWr3XDZz" : {
        "annotationSubtitle" : "1 Cupertino CA",
        "annotationTitle" : "Apple Infinite Loop",
        "notes" : "Does it work?!",
    }

如何访问选定的autoID,以便更新特定的notes 节点。到目前为止,我拥有的最好的是:

guard let uid = Auth.auth().currentUser?.uid else { return }
    uidRef.child(uid).child("annotations").(somehow access the specific childID).updateChildValues(["notes": newNotes])

任何帮助将不胜感激。在此先感谢

更新

annotationListItem 结构已创建:

struct AnnotationListItem {

let key: String?
var annotationTitle: String?
let annotationSubtitle: String?
let notes: String?
let ref: DatabaseReference?

init(key: String = "", annotationTitle: String, annotationSubtitle: String, notes: String) {
    self.key = key
    self.annotationTitle = annotationTitle
    self.annotationSubtitle = annotationSubtitle
    self.notes = notes
    self.ref = nil
}

init(snapshot: DataSnapshot) {
    key = snapshot.key
    let snapshotValue = snapshot.value as! [String: AnyObject]
    annotationTitle = snapshotValue["annotationTitle"] as? String
    annotationSubtitle = snapshotValue["annotationSubtitle"] as? String
    notes = snapshotValue["notes"] as? String
    ref = snapshot.ref
}

init(Dictionary: [String: AnyObject]) {
    self.key = Dictionary["key"] as? String
    self.annotationTitle = Dictionary["annotationTitle"] as? String
    self.annotationSubtitle = Dictionary["annotationSubtitle"] as? String
    self.notes = Dictionary["notes"] as? String
    self.ref = nil
}

func toAnyObject() -> Any {
    return [
        "annotationTitle": annotationTitle as Any,
        "annotationSubtitle": annotationSubtitle as Any,
        "notes": notes as Any
    ]
}
}

更新

annotationListItem 是这样创建并存储在 Firebase 中的:

// Using the current user’s data, create a new AnnotationListItem that is not completed by default
    let uid = Auth.auth().currentUser?.uid
    guard let email = Auth.auth().currentUser?.email else { return }
    let title = placemark.name
    let subtitle = annotation.subtitle
    let notes = ""

    // declare variables
    let annotationListItem = AnnotationListItem(
        annotationTitle: title!,
        annotationSubtitle: subtitle!,
        notes: notes)

    // Add the annotation under their UID
    let userAnnotationItemRef = uidRef.child(uid!).child("annotations").childByAutoId()
    userAnnotationItemRef.setValue(annotationListItem.toAnyObject())

【问题讨论】:

  • 你能出示AnnotationListItem的代码吗?
  • 你的意思是它是如何创建的或具体的结构?
  • 请看具体结构代码
  • 已更新。里面可能有一些不必要的东西,但我是 Swift 的新手,它是我查找过的不同东西的大量组合
  • 我可以看到您将 autoChildId 的值存储为 key 在您的结构中,对吗?所以我认为您可以使用它来更新数据库中的子值,请检查您是否理解并询问您是否遇到问题

标签: ios swift firebase firebase-realtime-database


【解决方案1】:

我认为您只需要这样做:(因为您已将注释声明为全局)

 guard let uid = Auth.auth().currentUser?.uid else { return } 
uidRef.child(uid).child("annotations").(note.key).updateChildValues(["notes": newNotes])

在你更改注释的方法内

【讨论】:

    【解决方案2】:

    如果我没记错的话,你是在创建一个自定义对象的数组吗?

    var newAnnotations: [AnnotationListItem] = []
    

    您可以执行以下操作:var newAnnotations: [(key: String, value: [String : Any])] = []Any 仅当您将拥有 StringsIntegers 等时。如果它只是 String,则将其指定为 String .

    访问密钥将是:newAnnotations[indexPath.row].key 在您的 cellForRowAtIndex 或您的 tableView 中。访问值将是:newAnnotations[indexPath.row].value["NAME"]

    您可以拥有一个单独的数组来保存密钥,然后将其与您的人口同时追加:

    for item in snapshot.children {
          guard let itemSnapshot = task as? FDataSnapshot else {
               continue
          }
          let id = task.key //This is the ID
          let annotationItem = AnnotationListItem(snapshot: item as! DataSnapshot)
          newAnnotations.append(annotationItem)
    }
    

    您可以做的另一件事是在您的 firebase 调用中再上一层:

    if let uid = Auth.auth().currentUser?.uid {
            uidRef.child(uid).child("annotations").observeSingleEvent(of: .value, with: {snapshot in
                if snapshot is NSNull{
                    //Handles error
                } else{
                    if let value = snapshot.value as? NSDictionary{ //(or [String: String]
                        //set localDictionary equal to value
                    }
                }
                self.tableView.reloadSections([0], with: .fade)
            })
        }
    

    然后当你选择一行时: let selectedItem = localDictionary.allKeys[indexPath.row] as! String //这是你传递给viewController的ID。

    【讨论】:

    • 感谢您的回复。我将研究它以了解您与我分享的内容。我与 3stud1ant3 进行了长时间的讨论,我们发现了另一种解决方案,因此我将不得不接受他的回答。还是谢谢你
    • 别担心!很高兴您收到答复!
    猜你喜欢
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2017-03-28
    • 1970-01-01
    相关资源
    最近更新 更多