首页 > 解决方案 > 您如何创建一个必须对 firebase 数据库进行查询并将查询值作为 int 返回的函数?

问题描述

我们目前正在制作一个 iOS 应用程序,并使用 firebase 作为其数据库。请在下面找到我们的代码。

static func getTilesPerRow () -> Int{

    let user = Auth.auth().currentUser
    guard let uid = user?.uid else {
        return -2
    }
    var ref: DatabaseReference!
    ref = Database.database().reference()
    let userRef = ref.child("user").child(uid)

    var num = -1

    let queue = DispatchQueue(label: "observer")

    userRef.child("tilesPerRow").observe(DataEventType.value, with: { (snapshot) in
        // Get user value
        print("now inside the observe thing------------------")
        let value = snapshot.value as? NSDictionary
        num = snapshot.value as? Int ?? 0
        print("just updated the number to ", num)
        print("the snapshot is ", snapshot)
        print("the value is ", value)
        print("the real value is", snapshot.value)
        print("just making sure, the number that was set is ", num)

    }) { (error) in
        print("there was an error!!!!!!!!!!!!!!!!!")
        print(error.localizedDescription)
    }

    print("about to return from the function ", num)
    return num
}

目前在运行此代码时,我们得到以下输出。

about to return from the function  -1
now inside the observe thing------------------
just updated the number to  5
the snapshot is  Snap (tilesPerRow) 5
the value is  nil
the real value is Optional(5)
just making sure, the number that was set is  5

我们的预期输出是:

now inside the observe thing------------------
just updated the number to  5
the snapshot is  Snap (tilesPerRow) 5
the value is  nil
the real value is Optional(5)
just making sure, the number that was set is  5
about to return from the function  5

这里的问题是我们试图获取查询找到的值,但是因为 .observe() 是异步的,所以函数在 .observe() 更新 num 的值之前完成。我们如何返回正确的值?

标签: iosswiftfirebasefirebase-realtime-database

解决方案


你没有。

要获得异步操作结果,请使用块。

static func getTilesPerRow (@escaping completion: (Int?)->Void ) {

    let user = Auth.auth().currentUser
    guard let uid = user?.uid else {
        completion(nil)
    }
    var ref: DatabaseReference!
    ref = Database.database().reference()
    let userRef = ref.child("user").child(uid)

    userRef.child("tilesPerRow").observeSingleEvent(DataEventType.value, with: { (snapshot) in
        // Get user value
        print("now inside the observe thing------------------")
        let value = snapshot.value as? NSDictionary
        let num = snapshot.value as? Int ?? 0
        completion(num)

    }) { (error) in
        print("there was an error!!!!!!!!!!!!!!!!!")
        print(error.localizedDescription)
        completion(nil)
    }
}

当结果准备好后,您将通过区块收到通知。成功后,您将获得num您正在寻找的实际信息或nil发生任何错误。

completion即使您可以通过在块中的参数列表中添加额外的参数来区分发生了什么样的错误。

你也可以使用协议,但这需要更多的知识,比如这段代码在哪个类中,谁是这类事情的调用者。将协议目标设置为调用者,完成后被调用的方法将根据发生的错误或成功情况触发不同的协议方法。

快乐编码。


推荐阅读