【问题标题】:Data inside Firebase Database read twice with an observeSingleEventFirebase 数据库中的数据使用 observeSingleEvent 读取两次
【发布时间】:2017-11-06 16:29:17
【问题描述】:

现在已经有几个小时了,我正在尝试挖掘 Internet 论坛以尝试找到解决我的问题的方法,但我无法弄清楚发生了什么,所以我希望这里的人可以提供帮助)

我有一个 swift 应用程序,在我的一个视图控制器上,我想做的是从 Firebase 数据库中检索数据并将它们显示在我的 tableview 上。

在这里您可以看到我的数据是如何组织的。 Firebase org of data

为了获取我的 tableview 中的行数,我将其放入 viewWillAppear 部分

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Count the number contacts to get the correct number of lines in the table

        let ref_table = ref.child("users").child((user?.uid)!).child("emergencyContacts")
        print("Starting observing")
        ref_table.observe(.value, with: { (snapshot: DataSnapshot!) in
            print("Got snapshot")
            print(snapshot.childrenCount)
            let count = snapshot.childrenCount
            self.numberOfContact = Int(count)
            self.UI_contactsTableView.reloadData()
            ref_table.removeAllObservers()
        })
        print("Returning count")
    }

然后,要获得行数,我有这个

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("Number of contact TV: \(numberOfContact)")
        return numberOfContact
    }

并填充我的表格视图的单元格

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "contact-cell") as! EmergencyContactCell
        print("value of numberOfContact \(numberOfContact)")
        ref.child("users").child((user?.uid)!).child("emergencyContacts").observeSingleEvent(of: .value, with: { (snapshot: DataSnapshot) in
                print("snapshot value \(snapshot.value!)")

                for rest in snapshot.children.allObjects as! [DataSnapshot] {
                    guard let restDict = rest.value as? [String:Any] else { continue }
                    let firstName = restDict["contact_firstName"] as? String ?? ""
                    cell.UI_fullName.text = "\(firstName)"
                }
            })
        return cell
    }

我认为这就是它变得糟糕的地方,因为在控制台中,无论我做什么,我都会不断显示 2 组数据,所以我的单元格总是填充有相同的名称,如您所见 here

这也是我程序执行后控制台的截图。

Starting observing
Returning count
Number of contact TV: 0
Number of contact TV: 0
Number of contact TV: 0
Got snapshot
2
Number of contact TV: 2
value of numberOfContact 2
value of numberOfContact 2
snapshot value {
    1ArkUu6pMPZPgf3pGFAvvxHiTPFaf5Cl =     {
        "contact_firstName" = Kate;
        "contact_lastName" = Bell;
        "contact_phoneNumber" = "(555) 564-8583";
    };
    s8haDrYYAT9Y12ZnmAfE87pDyjDZGwjx =     {
        "contact_firstName" = Daniel;
        "contact_lastName" = Higgins;
        "contact_phoneNumber" = "555-478-7672";
    };
}
snapshot value {
    1ArkUu6pMPZPgf3pGFAvvxHiTPFaf5Cl =     {
        "contact_firstName" = Kate;
        "contact_lastName" = Bell;
        "contact_phoneNumber" = "(555) 564-8583";
    };
    s8haDrYYAT9Y12ZnmAfE87pDyjDZGwjx =     {
        "contact_firstName" = Daniel;
        "contact_lastName" = Higgins;
        "contact_phoneNumber" = "555-478-7672";
    };
}

提前感谢您的帮助:)

【问题讨论】:

  • 好吧,但为什么它会严重填满我的单元格呢?

标签: swift firebase firebase-realtime-database tableview


【解决方案1】:

你的 cellForRowAtIndex Path 方法有一个错误。

 `ref.child("users").child((user?.uid)!).child("emergencyContacts").observeSingleEvent(of: .value, with: { (snapshot: DataSnapshot) in'

上述行在每次调用 cellForRowAtIndexPath 方法时返回所有紧急联系人。

在你的 for 循环中,你总是循环并选择最后一个值。

您需要提取特定索引路径的值。

【讨论】:

    【解决方案2】:

    我想通了,我尝试了一个完全不同的推理并且它奏效了。我实际上使用了一个处理程序来管理所有这些。我在这里发布我的代码,它可以帮助那些遇到我几个小时前遇到同样麻烦的人。

    var emergencyContactList = [EmergencyContact]()
    
    
    override func viewDidLoad() {
            super.viewDidLoad()
            ref = Database.database().reference()
            fetchUsers()
        }
    
    func fetchUsers() {
            refHandle = ref.child("users").child((user?.uid)!).child("emergencyContacts").observe(.childAdded, with: { (snapshot) in
                if let dictionary  = snapshot.value as? [String:AnyObject] {
                    print(dictionary)
                    let emergencyContact = EmergencyContact()
                    emergencyContact.setValuesForKeys(dictionary)
                    self.emergencyContactList.append(emergencyContact)
                    DispatchQueue.main.async {
                        self.UI_contactsTableView.reloadData()
                    }
                }
            })
        }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return emergencyContactList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
            let cell = tableView.dequeueReusableCell(withIdentifier: "contact-cell") as! EmergencyContactCell
            let _firstName = emergencyContactList[indexPath.row].contact_firstName ?? ""
            let _lastName = emergencyContactList[indexPath.row].contact_lastName ?? ""
            let _phoneNumber = emergencyContactList[indexPath.row].contact_phoneNumber ?? ""
            cell.UI_fullName.text = "\(_firstName) \(_lastName)"
            cell.UI_phoneNumber.text = "\(_phoneNumber)"
            return cell
        }
    

    我有一个 swift 文件,除了 EmergencyContact.swift

    import Foundation
    
    class EmergencyContact: NSObject {
        @objc var contact_firstName:String?
        @objc var contact_lastName:String?
        @objc var contact_phoneNumber:String?
    }
    

    现在它就像一个魅力! 感谢 TheAppMentor 抽出时间回答我:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-28
      • 2021-07-29
      • 2018-02-17
      • 2018-05-19
      • 2017-10-13
      • 2017-10-10
      相关资源
      最近更新 更多