issues loading items from firebase to a pickerview

后端 未结 1 698
再見小時候
再見小時候 2021-01-27 23:23

I have successfully created a QuestionModel class which retrieves items from firebase such, as a Question, string of answers and a correct question. I am however now having diff

相关标签:
1条回答
  • 2021-01-27 23:51

    Firebase functions do not (and should not) return values as they are asynchronous.

    So the return quiz line will fail most of the time as it will try to return data before Firebase has had time to retrieve it from the server.

    When coding with Firebase, data is only valid inside the closure following the function. So for example, this what NOT to do:

    func someFunc() {
        ref.child("Questions").child("Q1").observe(.value, with: { snapshot in
          print(snap)
        })
    
        print(snap) //this will not print the snap as this line executes *before* the closure
    }
    

    So doing it the right way; retrieve the data from Firebase, populate the array and refresh the tableview all within the closure.

    static func populateArrayAndRefreshTableView()
    {
        var ref: FIRDatabaseReference!= FIRDatabase.database().reference()
        let questionsRef = ref.child("Questions")
    
        questionsRef.child("Q1").observeSingleEvent(of: .value, with: { snapshot in
            if let dataDict = snapshot.value as? [String: Any] {
                let quest = dataDict["Question"] as? String,
                let Answers = dataDict["Answers"] as? [String],
                let Correct = dataDict["Correct"] as? Int {
                self.quizArray.append(Question(q: quest, a: Answers, c: Correct))
                self.tableView.reloadData()
            }
        })
      } 
    }
    

    Also note that the original code was using observe(.value). That will leave an observer attached to the ref and if the question changes, the code will be called. It doesn't look like that should be the behavior so using observeSingleEvent will call it once without adding an observer.

    Finally - you may want to re-consider how the nodes are named in your structure. It's often best practice to disassociate node name keys from the data they contain.

    questions
       -UYiuokoksokda
          question: "What significant contribution to bioengineering was made on the Loonkerian outpost on Klendth?"
          correct_answer: answer_1
          answers:
            answer_0: "Left handed smoke shifter"
            answer_1: "The universal atmospheric element compensator"
            answer_2: "Warp coil nullification amplifier"
            answer_3: "H.A.L. 9000"
       -YY8jioijasdjd
          question: "What is Kiri-kin-tha's first law of metaphysics?"
          correct_answer: answer_2
          answers:
            answer_0: "No matter where you go, there you are"
            answer_1: "Only people with sunroofs use them"
            answer_2: "Nothing unreal exists"
            answer_3: "Gravity is heavy"
    

    The keys, UYiuokoksokda, are created with childByAutoId().

    If you need to query answers you may want to even denormalize them into their own node and use the question key as the node key for the answers or keep a child node with the question key.

    0 讨论(0)
提交回复
热议问题