我是Swift 3和Firebase的新手,所以在从两个不同的节点检索数据并在一个表视图单元格中显示数据时遇到了一些问题。我在Stack溢出中还发现了一些类似的问题,如下所示:
Firebase - iOS Swift: load table view cell with data retrieved from two separate child nodes
但是无法将其应用到我的代码中,因为这些示例对询问者太过具体,或者我对Firebase的知识缺乏阻碍了我对所提供的答案的进展。
我的应用程序是用Swift 3编写的,使用Xcode-8,并使用Firebase实现数据持久性。该应用程序的目的是允许用户提交不同的练习程序供其他用户使用。用户提交的程序与作者的uid相关联,我计划使用它从一个基于uid值的单独节点检索用户的用户名。
我的消防基地设置如下:
"programs" : {
"-KYF3o3YD6F3FEXutuYH" : {
"content" : "Program Content Goes Here...",
"duration" : "4 Weeks",
"title" : "Chest Blast",
"type" : "Hypertrophy",
"uid" : "oLy9GOzDyKht7WWVZgpd3jPHxsE3"
},
"-KYF4ev88FQ2nEr6yTOW" : {
"content" : "Program Content Goes Here...",
"duration" : "6 Weeks",
"title" : "Full Back Workout",
"type" : "Strength",
"uid" : "oLy9GOzDyKht7WWVZgpd3jPHxsE3"
},
"-KZRYF9A8-8OHCNzOoPT" : {
"content" : "Eugene and Eamon",
"duration" : "4 Weeks",
"title" : "abc",
"type" : "abc",
"uid" : "oLy9GOzDyKht7WWVZgpd3jPHxsE3"
},
"-KbKNdrAcBarpaNoGf_e" : {
"content" : "Test",
"duration" : "test",
"title" : "New Test",
"type" : "test",
"uid" : "oLy9GOzDyKht7WWVZgpd3jPHxsE3"
},
"-KbKnXnyzj_EJp_wNw5y" : {
"content" : "1. Barbell Bench Press\n\nWhy it's on the list: You can generate the most power with barbell lifts, so the standard barbell bench allows you to move the most weight. It's also an easier lift to control than pressing with heavy dumbbells. The exercise is easy to spot and relatively easy to learn (if not master), There are plenty of bench-press programs you can follow to increase your strength.\n\n1. Barbell Bench Press\n\nWhy it's on the list: You can generate the most power with barbell lifts, so the standard barbell bench allows you to move the most weight. It's also an easier lift to control than pressing with heavy dumbbells. The exercise is easy to spot and relatively easy to learn (if not master), There are plenty of bench-press programs you can follow to increase your strength.",
"duration" : "1",
"title" : "1",
"type" : "1",
"uid" : "oLy9GOzDyKht7WWVZgpd3jPHxsE3"
}
},
"users" : {
"hds1WketiAUELVDOz1Dprvlu0KE3" : {
"username" : "Example"
},
"oLy9GOzDyKht7WWVZgpd3jPHxsE3" : {
"username" : "Test"
}
}应用程序中的表如下所示:

正如你所看到的,目前作者只是被他们的uid所指示。这很容易,因为我将它存储在与显示的所有其他数据相同的位置,但我需要使用这个uid值搜索另一个节点,获取与它关联的用户名,并在当前显示uid的位置显示它。
下面是我用来检索和显示数据的代码。我的主要问题是:
1:我可以使用什么查询来搜索用户节点中匹配的uid,并只获取此人的用户名并将其显示在表视图中?
他说:我应该把这个查询放在代码中的什么地方?我想把它放在func tableView()方法中,因为每次向单元格中添加新的帖子时,我都可以搜索用户,这样我就不必再创建另一个NSMutable数组来容纳那些甚至没有帖子的用户。非常感谢您的帮助。
@IBOutlet weak var programsTableView: UITableView!
var programs = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
self.programsTableView.delegate = self
self.programsTableView.dataSource = self
//Call load data method to populate table with data from Firebase
loadData()
}
//Method to load data from Firebase
func loadData(){
FIRDatabase.database().reference().child("programs").observeSingleEvent(of: .value, with: { (snapshot) in
//Snapshot holds value and it is casted to NS Dictionary
if let programsDictionary = snapshot.value as? [String: AnyObject]{
for program in programsDictionary{
self.programs.add(program.value)
}
self.programsTableView.reloadData()
}
})
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! AllProgramsTableViewCell
// Configure the cell...
let program = self.programs[indexPath.row] as! [String: AnyObject]
//Populate row
//Grab title and add it to cell
cell.titleLabel.text = program["title"] as? String
//Grab type and add it to cell
cell.typeLabel.text = program["type"] as? String
//Grab duration and add it to cell
cell.durationLabel.text = program["duration"] as? String
//Grab content and add it to cell
cell.contentTextView.text = program["content"] as? String
//Grab author and add it to cell
cell.authorLabel.text = program["uid"] as? String
return cell
}发布于 2017-01-28 14:18:34
帮你做几件事。
1:我可以使用什么查询来搜索用户节点中匹配的uid,并只获取此人的用户名并将其显示在表视图中?
首先,更改用户节点并利用uid作为每个用户的键。
users
uid_0
name: "Hans"
userName: "pump_u_up"
uid_1
name: "Franz"
userName: "abs_of_steel"这就避免了查询。查询比观察“更重”,占用的资源也更多。通过使用uid,您可以直接捕获用户信息。例如:
let userRef = rootRef.child("uid from programs node")
userRef.observeSingleEvent(of: .value, with: { snapshot in
let userDict = snapshot.value as! [String:AnyObject]
let userName = userDict["userName"] as! String
print(userName)
})他说:我应该把这个查询放在代码中的什么地方?我想把它放在func tableView()方法中,因为每次向单元格中添加新的帖子时,我都可以搜索用户,这样我就不必再创建另一个NSMutable数组来容纳那些甚至没有帖子的用户。非常感谢您的帮助。
现在您已经有了捕获用户信息的代码,添加它是一个简单的过程,不过,我建议您采用一种与发布的方式略有不同的方法。
从ProgramClass开始
class ProgramClass {
var key = ""
var content = ""
var duration = ""
var username = ""
}并以如下方式填充数据源:
ref.child("programs").observeSingleEvent(of: .value, with: { (snapshot) in
for snap in snapshot.children {
let programSnap = snap as! FIRDataSnapshot
let programKey = programSnap.key //the key of each program
let programDict = programSnap.value as! [String:AnyObject] //program child data
var aProgram = ProgramClass()
aProgram.key = programKey
aProgram.content = programDict["content"] as! String
//etc
let uid = programDict["uid"] as! String
let userRef = ref.child("users").child(uid)
userRef.observeSingleEvent(of: .value, with: { snapshot in
let userDict = snapshot.value as! [String:AnyObject]
let userName = userDict["userName"] as! String
aProgram.username = userName
self.programsArray.append[aProgram]
})
}
}上面的代码可以大大缩短,但为了可读性,它会更冗长。
哦,别忘了用一种快速的方式定义数据源数组:
var programsArray = [ProgramClass]()https://stackoverflow.com/questions/41909871
复制相似问题