gpt4 book ai didi

ios - 从 Firebase RT 数据库中提取数据时遇到问题

转载 作者:行者123 更新时间:2023-12-04 17:16:04 24 4
gpt4 key购买 nike

对编码非常陌生,如果这里有什么特别明显的地方,我们深表歉意。

我正在开发一个应用程序,可以用来跟踪我的举重分配。我这样写数据:

public func writeNewExercise(splitName: String, day: Int, exerciseNum: Int, exerciseName: String, sets: String, repsSecs: String, isTimed: Bool, completion: @escaping (Bool) -> Void) {

let user = AuthManager.shared.user
var exerciseRef: DatabaseReference!
exerciseRef = Database.database().reference(withPath: "\(user.uid)/splits/\(splitName)/day \(day)/exercise \(exerciseNum)")

var dataDictionary: [String: Any] = [:]
dataDictionary["Exercise Name"] = exerciseName
dataDictionary["Sets"] = sets
dataDictionary["Reps or Secs"] = repsSecs
dataDictionary["Is Timed"] = isTimed

exerciseRef.setValue(dataDictionary) { error, _ in
if error == nil {
completion(true)
return
} else {
completion(false)
return
}

}

}

这为我提供了一个 Firebase 中的 JSON 字典,如下所示:

{
"8aIzPgurRLPPEYDpXWv54r5JjvH3" : {
"splits" : {
"Test Split" : {
"day 1" : {
"exercise 0" : {
"Exercise Name" : "Curls",
"Is Timed" : false,
"Reps or Secs" : "12",
"Sets" : "4"
}
}
}
}
},

我现在想做的是提取这些数据,这样我就可以将每个练习插入到 tableView 单元格中。不想对它做任何花哨的事情——只是能够查看它,这样我就可以跟随我的拆分。我这样做更多是为了练习而不是实用性。我试过大约 15 种不同的方式提取数据,但无论我做什么都行不通。我完全被难住了。这是我现在拥有的代码:

    public func downloadPost(splitName: String, day: Int, completion: @escaping (Bool) -> Void){

let user = AuthManager.shared.user
var exerciseRef: DatabaseReference!
exerciseRef = Database.database().reference()

var exerciseArray = [Exercise]()

exerciseRef.child("Users").child(user.uid).child("splits").child(splitName).child("day \(day)").observe(.value) { snapshot in

if snapshot.exists(){
for x in 0...100{

let nameValue = snapshot.childSnapshot(forPath: "exercise \(x)/Exercise Name").value
let setsValue = snapshot.childSnapshot(forPath: "exercise \(x)/Sets").value
let repsOrSecsValue = snapshot.childSnapshot(forPath: "exercise \(x)//Sets/Reps or Secs").value
let isTimedValue = snapshot.childSnapshot(forPath: "exercise \(x)/Sets/Is Timed").value

let exercise = Exercise(name: "\(nameValue!)",
sets: "\(setsValue!)",
repsOrSecs: "\(repsOrSecsValue!)",
isTimed: isTimedValue as? Bool ?? false)
print(exercise.name)
print(exercise.sets)
print(exercise.repsOrSecs)
print(exercise.isTimed)
exerciseArray.append(exercise)
completion(true)
return
}
} else {
print("no snapshot exists")
}

print(exerciseArray)

}
}

Exercise 是我创建的自定义类,它具有名称、组数、重复次数和 Bool“isTimed”。此代码打印:

没有快照存在,[]

尝试其他的东西,我已经得到它来打印类似的东西:

空,0,0,假的

我尝试过的其他一些东西是:

  • 使用斜杠导航而不是在 .observe.value 中链接 .childs
  • 使用 .getData 代替 .observe
  • 到处乱扔 DispatchQueue.main.async
  • 将exerciseRef设为整个数据库,然后在赋值snapshot.value时调用到具体点
  • 还有很多

此时我可能已经为此投入了大约 15 个小时,但我真的想不通。任何帮助将不胜感激。我会密切关注这篇文章,并在需要时发布我可能遗漏的任何信息。

谢谢!

更新

使用下面 Medo 提供的代码,一切正常。对于其他尝试这样做的人,在按照 Medo 演示的方式拉出数组后,只需将 tableViewCell 中的所有标签设置为 ExportedArray[indexPath.row].theClassPropertyYouWant

最佳答案

这是我的解决方案:

public func downloadPost(splitName: String, day: Int, completion: @escaping (([Exercise]) -> ())){

let user = AuthManager.shared.user
var exerciseRef: DatabaseReference!
exerciseRef = Database.database().reference()

var exerciseArray = [Exercise]()

exerciseRef.child(user.uid).child("splits").child(splitName).child("day \(day)").observe(.value, with: { snapshot in

guard let exercises = snapshot.children.allObjects as? [DataSnapshot] else {
print("Error: No snapshot")
return
}



for exercise in exercises {
let exerciseData = exercise.value as? [String:Any]

let exerciseName = exerciseData["Exercise Name"] as? String
let isTimed = exerciseData["Is Timed"] as? Bool
let repsOrSecs = exerciseData["Reps or Secs"] as? String
let sets = exerciseData["Sets"] as? String

let exerciseIndex = Exercise(name: "\(exerciseName)",
sets: "\(sets)",
repsOrSecs: "\(repsOrSecs)",
isTimed: isTimed)

exerciseArray.append(exerciseIndex)

}
completion(exerciseArray)
}
}

您可以像这样调用函数 downloadPost 并从中提取数组:

downloadPost(splitName: "", day: 0, completion: {
aNewArray in

// aNewArray is your extracted array [Exercise]
print("\(aNewArray)")

})

需要注意的几点:

  1. 如果您想确保按顺序存储您的练习(并按顺序提取数据),那么不要将练习 0、1、2...(在您的数据库中)命名为 id称为“childByAutoId”。当您添加/推送或提取该数据时,Firebase 会自动为您排序。将您的 writeNewExercise 函数替换为:

    let user = AuthManager.shared.user
    var exerciseRef: DatabaseReference!
    let key = Database.database().reference().childByAutoId().key ?? ""
    exerciseRef = Database.database().reference(withPath: "\(user.uid)/splits/\(splitName)/day \(day)/\(key)")

    var dataDictionary: [String: Any] = [:]
    dataDictionary["Exercise Name"] = exerciseName
    dataDictionary["Sets"] = sets
    dataDictionary["Reps or Secs"] = repsSecs
    dataDictionary["Is Timed"] = isTimed

    exerciseRef.setValue(dataDictionary) { error, _ in
    if error == nil {
    completion(true)
    return
    } else {
    completion(false)
    return
    }

    }
  2. Firebase 实时数据库是广度优先搜索和下载。所以你应该尽可能地扁平化你的数据库结构。这意味着观察 exerciseRef.child("Users").child(user.uid).child("splits").child(splitName).child("day\(day)") 会仍然下载所有练习日。

关于ios - 从 Firebase RT 数据库中提取数据时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68695877/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com