在 Firebase 中,检索到的数据不会从 .observeEventType 方法中取出

Posted

技术标签:

【中文标题】在 Firebase 中,检索到的数据不会从 .observeEventType 方法中取出【英文标题】:In Firebase, retrieved data doesn't get out from the .observeEventType method 【发布时间】:2016-09-07 11:30:49 【问题描述】:

我在项目中定义了一个类,用于管理我在 Firebase 中设置的数据库。以下是到目前为止我对课程所做的工作。

import Foundation
import Firebase

class db
    class func getPrim() -> [String]
        var ret = [String]()

        let ref = FIRDatabase.database().reference()

        ref.child("bunya1").observeEventType(FIRDataEventType.Value, withBlock: 
            s in

            ret = s.value! as! [String]

        )

        print("ret: \(ret)")
        return ret
    

并且该方法在print() 方法中调用,例如print(db.getPrim())。但是控制台(或终端?无论如何,xcode底部的屏幕..)所说的只是一个空数组。我用print("-----------------------") 接受了上面的声明。

-----------------------
ret: []
[]
-----------------------
2016-09-07 20:23:08.808 이모저모[36962:] <FIRAnalytics/INFO> Successfully created Firebase Analytics App Delegate Proxy automatically. To disable the proxy, set the flag FirebaseAppDelegateProxyEnabled to NO in the Info.plist
2016-09-07 20:23:08.815 이모저모[36962:] <FIRAnalytics/INFO> Firebase Analytics enabled

似乎.observeEventType() 方法中的ret 不会将其值从方法块中取出。据我所知,数据应该被保留。任何人都可以给我一个提示吗?我仍然不明白代码块作为方法参数是如何工作的。谢谢!!

【问题讨论】:

我在赋值语句ret = s.value! as! [String] 的正下方写了print("ret: \(ret)")。这个是在我发布的控制台消息出现几秒钟后打印出来的。 根据定义,所有 firebase 操作都是异步的。因此,当您的打印语句被调用时,尚未从 firebase 获取数据。 @AndréKool 将其发布为答案 @AndréKool 你能告诉我更多细节吗 【参考方案1】:

根据定义,所有 firebase 操作都是异步的,这意味着您的程序在转到代码中的下一条语句之前不会等待来自 firebase 的数据。因此,当您的打印语句被调用时,尚未从 firebase 获取数据。

查看this answer 了解更多信息。

【讨论】:

【参考方案2】:

André(以及 Vikrum 答案的链接)确实是发生这种情况的原因。但是,如果您在代码中添加一些日志语句,通常最容易理解:

class func getPrim() -> [String]
    let ref = FIRDatabase.database().reference()

    print("Before observer");
    ref.child("bunya1").observeEventType(FIRDataEventType.Value, withBlock: 
        s in

        print("In observer block");

    )
    print("After observer");

    return "..."

当您运行此代码时,日志记录将按以下顺序进行:

在观察者之前

观察者之后

在观察者回调中

这可能不是您期望它们出现的顺序。但这绝对解释了为什么您在 sn-p.xml 中返回一个空数组。如果块内的代码尚未运行,则该项目尚未添加到数组中。

这个顺序颠倒的原因正如 André 和 Vikrum 所说:对 Firebase 的调用是异步发生的。由于它可能需要一些时间(特别是如果这是您第一次访问数据库),Swift 代码会继续执行以确保应用程序保持响应。一旦数据从 Firebase 传回,您的块就会被调用(因此有时称为“回调”)并且您会获取数据。

【讨论】:

谢谢!那么我应该使用sleep() 方法还是等待.observeEventType() 完成执行? 不。你应该摆脱“先做这个,然后做那个”的想法,而是采用“如果发生这种情况,我会做那个作为回应”的心态。请参阅 André 链接到的 Vikrum 的答案,了解相关示例。

以上是关于在 Firebase 中,检索到的数据不会从 .observeEventType 方法中取出的主要内容,如果未能解决你的问题,请参考以下文章

如何在 vue js 中显示从 firebase 检索到的标题标签 <h1> </h1> 的数据?

Recyclerview 不会从 firebase 检索数据

Android - 持久化从 Firebase 检索到的数据

Firebase - iOS Swift:使用从两个单独的子节点检索到的数据加载表格视图单元格

试图快速删除从firebase检索到的数组中的重复值

从 firebase 检索数据并将其显示在可扩展的 recyclerview 中