ios - 你如何制作一个必须对 firebase 数据库进行查询并将查询值作为 int 返回的函数?

标签 ios swift firebase firebase-realtime-database

我们目前正在制作一个 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 的值之前完成。我们如何返回正确的值?

最佳答案

你不知道。

要获得异步操作结果,您可以使用 block 。

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)
    }
}

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

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

您也可以使用协议(protocol),但这需要更多的知识,例如,这段代码位于哪个类中,谁是调用者等等。将协议(protocol)目标设置为调用者,调用方法完成后将根据发生的错误或成功案例触发不同的协议(protocol)方法。

快乐编码。

关于ios - 你如何制作一个必须对 firebase 数据库进行查询并将查询值作为 int 返回的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53357251/

相关文章:

ios - 如何使用刷新控件限制拉动距离?

iphone - 从 NSDictionary 我只得到 0 或 null 我该怎么办?

iOS 应用程序切片或细化不起作用

xcode - AVPlayer 一旦移动到背景就卡住

android - 如何通过蓝牙连接从 Android 应用程序在 Raspberry Pi 上运行脚本

ios - 自定义协议(protocol)不发送消息

ios - 我可以在不将联系人保存到 contactStore 的情况下使用 View CNContactViewController 吗?

json - 将 AnyObject 转换为 Double

firebase - Angular 8 Firebase 使用 Google 登录失败,之前的项目无法正常工作

javascript - Google Firebase 忘记密码