databaseReference.observe(DataEventType.value,其中:{(DataSnapshot)始终无法正常工作

时间:2017-12-02 02:42:44

标签: swift firebase firebase-realtime-database

func checkPaid(utilityId : String) -> Int{

        var amount:String = ""
        var status = 0
        print("inside new function ")
        print ("\(utilityId) inside new function ")
        self.databaseRefPayment.observe(DataEventType.value, with:{(DataSnapshot) in
          if  DataSnapshot.childrenCount > 0 {
            for payments in DataSnapshot.children.allObjects as! [DataSnapshot]{
                  var paymentsObject = payments.value as? NSDictionary

                    /*
                    if(paymentsObject!["month"] as! String == monthCheck && paymentsObject!["year"] as! String == monthCheck && paymentsObject!["utilityid"] as! String == utilityId as! String){ */
                    if(paymentsObject!["utilityId"] as! String == utilityId){

                        amount = paymentsObject!["amount"] as! String
                        print(amount)
                        print("Ypur program is working perfect")
                        status = 1

                    }
                }
            }
        })

        return status
  }

上述功能是根据函数中传递的utilityId值过滤付款节点中的数据。但奇怪的是observe(DataEventType.value, with:{(DataSnapshot)这个事件并没有一直被触发。它只是不必要地跳过那部分。我对firebase非常陌生,对这些不可预测的行为非常生气。请帮帮我。随时可以要求任何澄清。

2 个答案:

答案 0 :(得分:1)

firebase在不同的线程中执行firebase查询函数,所以在你调用paid()之后,它在另一个线程中运行checkpaid()firebase查询,它将从函数返回,尽管你的查询在后台运行..看起来好像,checkpaid()不起作用,但实际上它在另一个线程上运行。

我认为您首先从付款中获取所有必需的数据,并将其存储在列表中,然后使用该列表与实用程序进行比较。

答案 1 :(得分:0)

每次调用此函数时,它会为您正在观察的任何子节点添加/重置键值观察器除非更改,否则它实际上不会检查该值。我相信您打算通过某种方式调用checkPaid(utilityId :)来检查孩子是否“付款”。如果直接读取单个快照的值,则无需添加KVO。请考虑以下事项:

func checkPaid(utilityId: String) -> Bool {
    //Assume it is not paid if we cannot verify it.
    var isPaid = false
    //Create a new reference to Firebase Database
    var ref: DatabaseReference!
    ref = Database.database().reference().child(utilityId)

    //Get the values for the child, test if it is paid or not.
    ref.queryOrderedByValue().observeSingleEvent(of: .value) { (snapshot) in
        if (snapshot.value is NSNull) {
            print("No Child With \(utilityId) Exists")
        } else  {
            //child with utilityId exists, in case multiple utilityId's exist with the same value..
            for child in snapshot.children.allObjects as! [DataSnapshot] {
                if let values = child.value as? [String : AnyObject] {

                    let uid = child.key //utilityId

                    var month:String = ""
                    var year:String = ""
                    var amount:String = ""
                    //var amount:Double = 0.0

                    //get values from parent
                    if let m = values["month"] as? String {
                        month = m
                    }

                    if let y = values["year"] as? String {
                        year = y
                    }

                    if let a = values["amount"] as? String {
                        amount = a
                    }

                    /*
                     if let a = values["amount"] as? Double {
                        amount = a
                     }
                     */



                    //??
                    if ((month == monthCheck) && (year == monthCheck)) {
                        isPaid = true
                    }

                }
            }
        }

    return isPaid
}

我在这里做一个假设; utilityId是孩子的关键。 如果你有parentId的父节点,你在引用数据库时也必须横向化它们:

ref = Database.database().reference().child(utilities).child(utilityId) ..etc

如果您需要KVO来更新本地属性,我建议在viewDidLoad中添加/调用它,它的完成处理程序应该更新在Firebase中更改时更新的任何属性。