Ios 将FIREBASE嵌套子节点中的信息捕获到数组中,并将其传递给下一个ViewController XCODE

Ios 将FIREBASE嵌套子节点中的信息捕获到数组中,并将其传递给下一个ViewController XCODE,ios,swift,firebase,firebase-realtime-database,Ios,Swift,Firebase,Firebase Realtime Database,这段代码是我如何从数据库建模初始JSON抓取的。这一切在tableview中都可以正常工作。它还有一个包含许多问题的孩子。如图所示。我正在做一个琐事游戏。很简单 使用XCODE 9、Swift 4和FIREBASE 一切都是用硬编码数据工作的,但自从切换到FIREBASE后,我一直很难让它正常工作 我当前的问题是在用户导航时,在不同的屏幕上使用同一快照的不同方面 我对此进行了研究,我的问题只解决了一半。我知道如何从FIREBASE捕获快照,但我真正想做的是: 我有一个名为TITLE的孩子,在这个

这段代码是我如何从数据库建模初始JSON抓取的。这一切在tableview中都可以正常工作。它还有一个包含许多问题的孩子。如图所示。我正在做一个琐事游戏。很简单

使用XCODE 9、Swift 4和FIREBASE

一切都是用硬编码数据工作的,但自从切换到FIREBASE后,我一直很难让它正常工作

我当前的问题是在用户导航时,在不同的屏幕上使用同一快照的不同方面

我对此进行了研究,我的问题只解决了一半。我知道如何从FIREBASE捕获快照,但我真正想做的是:

  • 我有一个名为TITLE的孩子,在这个孩子里面,我有关于标题细节的值。每个标题都有一个名为QUESTIONBANK的子项,其中包含多个问题子项,每个问题子项都有值:问题、答案、答案等。因此,一个标题可以有许多问题,每个问题都有自己的答案

  • 在表格视图中,我通过快照抓取标题并显示它们。一切正常。我将其推送到一个数组中,并使用一个模型作为标题来动态显示它们。我还设置了一个缓存帮助器,允许在用户来回移动时在会话期间保存它

  • 问题

  • 然后,我想允许用户点击一个单元格,进入实际的琐事部分,并利用特定标题的题库子项中的问题。ie创建一系列问题,并在下一页使用选定的标题作为题库节点的参考,该标题是特定于该标题的
  • 问题是,一旦我在一个页面上使用了标题的快照,当用户选择标题并移动到另一个页面时,我就无法返回并为该标题创建一个包含所有问题和答案的数组

    我已经为此创建了模型,我知道它可以工作,因为在设置FIREBASE之前,我对它的数据进行了硬编码,并将所有硬编码数据替换为FIREBASE数据库、存储和身份验证

    这是一场斗争,因为我对这一切都很陌生,而我现在因为这件最新的事情撞到了墙。我不想花上几天或一周的时间去想办法


    感谢您的帮助

    让我从两个方面来回答这个问题。对问题的具体回答,然后建议使用不同结构的方法

    电影的结构和你的差不多

      "movies" : {
        "movie_id_0" : {
          "question_bank" : {
            "questions" : {
              "question_0" : {
                "correct_answer" : "HAL 9000",
                "question_text" : "Name of computer"
              }
            }
          },
          "title" : "2001, A Space Odyssey"
        },
        "movie_id_1" : {
          "question_bank" : {
            "questions" : {
              "question_0" : {
                "correct_answer" : "Ted Stryker",
                "question_text" : "Main character name"
              }
            }
          },
          "title" : "Airplane"
        }
      },
    
    下面的代码将读取电影节点,打印出每部电影的标题,然后是问题;为了简洁起见,我只为每部电影做了一个,但如果有更多的(问题1、问题2等),它们也会打印出来

    let ref = self.ref.child("movies")
    ref.observeSingleEvent(of: .value, with: { snapshot in
        if snapshot.exists() == true {
    
            for movieChild in snapshot.children { //this will iterate over every movie node
                let movieSnap = movieChild as! DataSnapshot //each movie is it's own snapshot
    
                let movieDict = movieSnap.value as! [String: Any]
                let title = movieDict["title"] as! String
                print(title)
    
                let questionBank = movieSnap.childSnapshot(forPath: "question_bank")
                let questions = questionBank.childSnapshot(forPath: "questions")
    
                for questionChild in questions.children {
                    let questionSnap = questionChild as! DataSnapshot
                    let questionDict = questionSnap.value as! [String: Any]
                    let question = questionDict["question_text"] as! String
                    let answer = questionDict["correct_answer"] as! String
                    print("  q: \(question)  a:\(answer)")
                }
            }
        } else {
            print("no snapshot found")
        }
    })
    
    以及输出

    2001, A Space Odyssey
      q: Name of computer  a:HAL 9000
    Airplane
      q: Main character name  a:Ted Stryker
    
    根据您的原始问题,上述代码将允许您访问问题库中的问题

    让我们看看替代结构:

    "movies" : {
       "movie_id_0" : {
          "title" : "2001, A Space Odyssey"
        },
    
    "questions" : {
       "question_0"
          "for_movie_id": "movie_id_0"
          "correct_answer" : "HAL 9000",
          "question_text" : "Name of computer"
       "question_1"
          "for_movie_id": "movie_id_0"
          "correct_answer" : "Stanley Kubrick",
          "question_text" : "Directed by?"
    
    首先要注意的是,问题库有一个子问题,然后有子问题(q0、q1等)。可以删除“问题”节点并向上移动所有子节点

    "movies" : {
      "movie_id_0" : {
        "question_bank" : {
          "question_0" : {
             "correct_answer" : "HAL 9000",
             "question_text" : "Name of computer"
           }
        },
      "title" : "2001, A Space Odyssey"
    },
    
    这是一个非常深层的结构,查询和处理起来会非常复杂。这里有一个更好的结构:

    "movies" : {
       "movie_id_0" : {
          "title" : "2001, A Space Odyssey"
        },
    
    "questions" : {
       "question_0"
          "for_movie_id": "movie_id_0"
          "correct_answer" : "HAL 9000",
          "question_text" : "Name of computer"
       "question_1"
          "for_movie_id": "movie_id_0"
          "correct_answer" : "Stanley Kubrick",
          "question_text" : "Directed by?"
    
    这将允许查询2001年的所有问题、太空漫游、HAL9000的所有答案以及斯坦利·库布里克导演的所有电影

    我甚至可以再做一步,在电影和问题之间添加一个反向关系

    "movies" : {
       "movie_id_0" : {
          "title" : "2001, A Space Odyssey"
          "questions": {
             "question_0": true
             "question_1": true
        },
    

    在Firebase中,让数据尽可能平坦是最好的做法。查看更多细节。

    这里有一个链接,指向一个类似的问题,但在这里没有解决:与其描述您的数据结构和代码,不如编辑您的问题以包含实际问题(如文本,请不要截图)。这样的MCVE是最有可能获得帮助的方式。您可以通过单击数据库中的“导出JSON”链接从数据库中获取JSON。我添加了一些代码片段。那么是否可以从单个JSON获取两个级别的数据?ie获取每个标题,然后同时获取与该标题关联的所有问题节点和值?不是说我想这么做,而是想知道。理想情况下,我希望能够在下面的ViewController上获取所选标题的问题。因此,如果要在屏幕快照中观察快照,则会加载所有数据;演员、导演、姓名、问题库以及问题库的所有子女。不清楚是什么阻止了您执行任务-如果您将快照存储在阵列中,那么您也可以访问该快照中的所有子数据。你能澄清实际的问题是什么吗?哇,非常感谢。我真的要坐下来好好消化它,因为我想和Firebase一起工作。这是我真正的弱点。数据库。我是Swift的新手,只在Firebase工作了几天。问题,您是否生成了ID?电影id和问题id?ie您没有使用childbyautoId?@ROKOKO请一般使用childbyautoId作为要迭代的键名(如本例所示)。为了可读性,我刚刚使用了电影和问题id。我希望这能有所帮助——如果有什么不清楚的地方,请告诉我。这是非常清楚的。我真的很感激。我想我的下一个障碍将是学习如何在需要编辑或删除时按ID搜索特定的标题。正如我所说,这个领域对我来说都是全新的。它需要时间,但要坚持下去。如果答案对你有帮助,一定要接受它,这样它才能帮助别人。是的,我会的。如果说我想在一个视图上对一个标题上的数据建模,那么稍后在多个视图上,我想将新数据存储到所讨论的标题上,这是不是我必须将标题存储为快照才能从视图传递到v