Быстрое отображение данных firebase в tableview не показано - PullRequest
0 голосов
/ 19 июня 2020

Я создаю приложение с firebase в качестве базы данных, и я, кажется, не могу показать свои данные в моем табличном представлении. Я проверяю свою базу firebase, все мои данные в порядке, даже когда я добавляю новые данные, данные сразу отображаются в моей базе данных. но похоже, что некоторые пропустили лог c у меня здесь .... может кто-нибудь мне помочь?

* Отредактируйте строку 1, где код не работает

это мой основной контроллер:

class MainController: UITableViewController, AddPatientControllerr {


private var patientLists = [PatientList]() 
var Segue : String = "PatientName"
var Segue2 : String = "PatientNotes"
let user : User = Auth.auth().currentUser! 

private var rootRef : DatabaseReference!// 1. buat nyambung ke root db

override func viewDidLoad() {
    super.viewDidLoad()
   
    self.rootRef = Database.database().reference() 
    
    populateList()
    
    tableView.delegate = self
    tableView.dataSource = self

}

// MARK : Firebase Function

private func populateList() {
    
    self.rootRef.child(self.user.emailWithoutSpecialChar).observe(.value) { (snapshot) in 
        
        self.patientLists.removeAll()
        
        let pasienListDict = snapshot.value as? [String:Any]  ?? [:] 
        
        for (key,_) in pasienListDict {
            
            if let pasienlistdict = pasienListDict[key] as? [String:Any]{

                if let pasienlist = PatientList(pasienlistdict) { // this line of code is not working 
                    self.patientLists.append(pasienlist)
                   
                }else {
                   print("your condition not working")
                }
            }
            
        }
            DispatchQueue.main.async {
           self.tableView.reloadData()
       }
        
        
    }
    
}

// MARK : Func delegate

func addPatientData(controller: UIViewController, nama: String, tglLahir: String, Telp: String, berat: String, Tinggi: String, golDarah: String) {
       
    let patientList = PatientList(name: nama, tglLahir: tglLahir, Telp: Telp, berat: berat, Tinggi: Tinggi, golDarah: golDarah)
       self.patientLists.append(patientList)
              
       let userRef = self.rootRef.child(self.user.emailWithoutSpecialChar)
       let patientListRef = userRef.child(patientList.name)
       patientListRef.setValue(patientList.toDictionary())
      
       controller.dismiss(animated: true, completion: nil)

       DispatchQueue.main.async {
           self.tableView.reloadData()
       }
   }

// MARK : Segue
   
   override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
       
       if segue.identifier == Segue {
           let nc = segue.destination as! UINavigationController
           let addPatientName = nc.viewControllers.first as! ProfileController
           addPatientName.delegate = self
           
           }
           
           else if segue.identifier == Segue2 {
           
           guard let indexPath = self.tableView.indexPathForSelectedRow else {return}
            
           let nc = segue.destination as! PasienProfileController
           nc.pasien = self.patientLists[indexPath.row]
     
       }
   
   }
 

//MARK : TableView

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        let pasienList = self.patientLists[indexPath.row]
        let pasienListRef = self.rootRef.child(pasienList.name)
        pasienListRef.removeValue()
    }
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
    return self.patientLists.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? MainCell else {return UITableViewCell()}
    let patientListt = self.patientLists[indexPath.row]
    
    cell.NameLbl.text = patientListt.name

    return cell
  }  
}

, и это модель, в которой я храню данные и словарь:

import Foundation

typealias JSONDictionary  = [String:Any]

class PatientList { 

var name : String!
var tglLahir : String!
var Telp : String!
var berat : String!
var Tinggi : String!
var golDarah : String!
var patientNote :[PatientNote] = [PatientNote]() //ini buat nyimpen notes2 dari tiap2 pasien 

init(name : String, tglLahir : String, Telp : String, berat : String, Tinggi : String, golDarah : String) {
    self.name = name
    self.tglLahir = tglLahir
    self.berat = berat
    self.Tinggi = Tinggi
    self.golDarah = golDarah
    self.Telp = Telp
}

init?(_ dictionary :[String:Any]){
    
    guard let name = dictionary["Name"] as? String else {
        return nil
    }
    guard let berat = dictionary["BeratBadan"] as? String else {
        return nil
    }
    guard let tglLahir = dictionary["TanggalLahir"] as? String else {
        return nil
    }
    guard let Tinggi = dictionary["TinggiBadan"] as? String else {
        return nil
    }
    guard let golDarah = dictionary["GolonganDarah"] as? String else {
        return nil
    }
    guard let Telp = dictionary["Telefon"] as? String else {
        return nil
    }
    self.name = name
    self.berat = berat
    self.tglLahir = tglLahir
    self.Tinggi = Tinggi
    self.golDarah = golDarah
    self.Telp = Telp
    let pasienListDictionary = dictionary["patientNote"] as? [JSONDictionary]
    
    if let dictionaries = pasienListDictionary {
        self.patientNote = dictionaries.compactMap(PatientNote.init)
    }
}

func toDictionary() -> [String:Any] { // ini buat dictionary buat convery object jd string:any, jd biar ga ngubah satu2 kl ada yg salah gituu
    
    return ["Name":self.name, "BeratBadan":self.berat, "TanggalLahir":self.tglLahir, "TinggiBadan":self.Tinggi, "golDarah":self.golDarah, "Telefon":self.Telp, "patientNote":self.patientNote.map{ patientNote in
        return patientNote.toDictionary()
    }]
}

}

, а это моя база данных:

[! [Firebase] [1 ]] [1]

для начала, мне просто нужно показать свое имя в моем табличном представлении, которое в этом случае я даже не могу показать данные имени в моем табличном представлении

Кажется, я не могу узнать почему данные не отображаются в моем tableview .... xcode не показывает ошибку

кто-нибудь может мне помочь? спасибо

firebase Json

"afipermanalivecom" : {
    "Apiyyy" : {
        "BeratBadan" : "",
        "Name" : "Apiyyy",
        "TanggalLahir" : "20-05-2020",
        "Telefon" : "",
        "TinggiBadan" : "",
        "golDarah" : "A+"
    },
    "CocaCola" : {
        "BeratBadan" : "80",
        "Name" : "CocaCola",
        "TanggalLahir" : "20-06-2020",
        "Telefon" : "0878099996049",
        "TinggiBadan" : "190",
        "golDarah" : "A-"
    },
    "Jamsey" : {
        "BeratBadan" : "",
        "Name" : "Jamsey",
        "TanggalLahir" : "19-06-2020",
        "Telefon" : "",
        "TinggiBadan" : "",
        "golDarah" : "A-"
    }
},

"puffygmailcom" : {
    "Batman" : {
        "Name" : "Batman"
    },
    "Stitchh" : {
        "Name" : "Stitchh"
    }
}

Ответы [ 3 ]

0 голосов
/ 20 июня 2020

Если вы хотите вернуть список данных, вам нужно будет использовать .childAdded вместо .value

Итак, ваш код будет примерно таким:

self.rootRef.child(self.user.emailWithoutSpecialChar).observe(.childAdded) { (snapshot) in

       // do your stuff here
}

* салям сезама оранг Индонезия :)

0 голосов
/ 21 июня 2020

Из кода и структуры вопроса видно, что есть список врачей и пациентов, пациенты которых являются дочерними узлами доктора. Я опубликую решение, а затем несколько важных рекомендаций по изменениям.

Вот существующая структура Firebase. Обратите внимание, что мы НЕ используем адреса электронной почты в качестве ключей узлов - это большая дополнительная работа, и если адрес электронной почты изменится, вся база данных будет просканирована, узлы прочитаны, удалены и перезаписаны. Ключи узлов Dynami c (те, которые могут изменяться, например, электронная почта) должны вместо этого генерироваться с помощью .childByAutoId - я использую doctor_0, doctor_1 et c для удобства чтения.

{
  "doctor_0" : {
    "name" : "Dr. Doolittle",
    "patient_list" : {
      "patient_0" : {
        "blood_type" : "O-",
        "name" : "Henry"
      },
      "patient_1" : {
        "blood_type" : "AB-",
        "name" : "Leroy"
      }
    }
  },
  "doctor_1" : {
    "name" : "Dr. McCoy",
    "patient_list" : {
      "patient_2" : {
        "blood_type" : "O+",
        "name" : "Steve"
      }
    }
  }
}

У меня два класса для хранения этих данных, DoctorClass и PatientClass, причем класс Patient является массивом внутри DoctorClass. Обратите внимание, что у Доктора может не быть пациентов, поэтому я рассматриваю это как необязательный.

var docAndPatientList = [DoctorClass]()

func loadDoctorsAndPatients() {
    let doctorsRef = self.ref.child("doctors") //self.ref points to *my* firebase
    
    doctorsRef.observeSingleEvent(of: .value, with: { snapshot in
        let allDoctorsSnapshot = snapshot.children.allObjects as! [DataSnapshot]
        for docSnap in allDoctorsSnapshot {
            let docId = docSnap.key
            let docName = docSnap.childSnapshot(forPath: "name").value as? String ?? ""
            let patientSnap = docSnap.childSnapshot(forPath: "patient_list")
            let doc = DoctorClass(withId: docId, andName: docName, maybePatientList: patientSnap)
            self.docAndPatientList.append(doc)
        }
    })
}

, а затем распечатайте их

func printDoctorsAndPatients() {
    self.docAndPatientList.forEach { doctor in
        print("Dr: \(doctor.doc_name)")
        for patient in doctor.patients {
            print("  patient: \(patient.patient_name)  bloodtype: \(patient.blood_type)")
        }
    }
}

и результат

Dr: Dr. Doolittle
  patient: Henry  bloodtype: O-
  patient: Leroy  bloodtype: AB-
Dr: Dr. McCoy
  patient: Steve  bloodtype: O+

Это будет работать с существующей структурой, но что, если, например, у пациента два доктора? Или что, если мы хотим запросить Firebase для всех пациентов с группой крови O-? Это не будет работать (легко) с этой структурой.

Вот лучший план

root_ref
   doctors
      doctor_0
         name : "Dr. Doolittle"
         patients
            patient_0 : true
            patient_1 : true
      doctor_1
         name : "Dr. McCoy"
         patients
            patient_2 : true

и пациенты

root_ref
   patients
      patient_0
         blood_type : "O-"
         doctors:
            doctor_0: true
         name : "Henry"
      patient_1
         blood_type : "AB-"
         doctors:
            doctor_0: true
         name : "Leroy"
      patient_2
         blood_type : "O+"
         doctors:
            doctor_1: true
         name : "Steve"

Эта структура обеспечивает большую гибкость запросов и масштабируемость.

0 голосов
/ 20 июня 2020

Просто несколько советов и, возможно, решение, я бы рекомендовал использовать firebase Cloud вместо firebase в реальном времени firebase, это намного быстрее и надежнее, особенно если вы пытаетесь запрашивать данные из массивов или словаря, я вижу, что вы пытаетесь получить данные из словаря, одна вещь, которую вы хотите отметить, это то, что firebase хранит ваш быстрый словарь как целевой C словарь, так что это одна вещь, которую вы хотите отметить! Попробуйте проверить, правильно ли вы использовали идентификаторы повторного использования.

Дайте мне знать, если вы все еще не можете его получить!

...