首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将数据从两个独立的Firebase节点加载到一个表视图单元中

将数据从两个独立的Firebase节点加载到一个表视图单元中
EN

Stack Overflow用户
提问于 2017-01-28 12:37:38
回答 1查看 1.3K关注 0票数 0

我是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值的单独节点检索用户的用户名。

我的消防基地设置如下:

代码语言:javascript
复制
    "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数组来容纳那些甚至没有帖子的用户。非常感谢您的帮助。

代码语言:javascript
复制
@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
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-28 14:18:34

帮你做几件事。

1:我可以使用什么查询来搜索用户节点中匹配的uid,并只获取此人的用户名并将其显示在表视图中?

首先,更改用户节点并利用uid作为每个用户的键。

代码语言:javascript
复制
users
  uid_0
    name: "Hans"
    userName: "pump_u_up"
  uid_1
    name: "Franz"
    userName: "abs_of_steel"

这就避免了查询。查询比观察“更重”,占用的资源也更多。通过使用uid,您可以直接捕获用户信息。例如:

代码语言:javascript
复制
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开始

代码语言:javascript
复制
class ProgramClass {
    var key = ""
    var content = ""
    var duration = ""
    var username = ""
}

并以如下方式填充数据源:

代码语言:javascript
复制
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]
        })
    }
}

上面的代码可以大大缩短,但为了可读性,它会更冗长。

哦,别忘了用一种快速的方式定义数据源数组:

代码语言:javascript
复制
var programsArray = [ProgramClass]()
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41909871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档