如何仅在从 Firebase 下载数据后执行操作

Posted

技术标签:

【中文标题】如何仅在从 Firebase 下载数据后执行操作【英文标题】:How to perform an action only after data are downloaded from Firebase 【发布时间】:2017-03-26 10:53:41 【问题描述】:

我试图弄清楚如何仅在 Firebase 中的 observeSingleEvent 完成工作后触发操作。

背后的原因是我需要做以下操作:

根据用户的一项输入,我需要从数据库中获取一些数据 当这些数据完全下载后,我需要对它们进行一点处理,并用于检索其他要显示给用户的数据

目前我正在使用此代码:

    let listOfTags = [String]()
    var outputArray = [String]()

    if listOfTags.count != 0 
        for tag in listOfTags 

            ref.child("tags").child(tag).observeSingleEvent(of: .value, with:  (snapshot) in

                if let temp = snapshot.children.allObjects as? [FIRDataSnapshot] 
                    for elem in temp 
                        outputArray.append(elem.key)
                    
                

                // ...
            )  (error) in
                print(error.localizedDescription)
            
        

        // HERE I WANT TO DO AN ACTION "ONLY" AFTER THE FOR LOOP IS
        // COMPLETED AND THE "outputArray" IS FILLED WITH ALL VALUES
        doSomethingHere()

    

但我注意到,当 outputArray 仍然为 EMPTY 时,函数 doSomethingHere() 会立即执行!所以它什么都不做。

那么我的问题是,如何构建程序,以便在下载过程完成后执行此功能?也许observeSingleEvent 不是要使用的正确Firebase 方法?对于这种特定情况,我不想观察任何变化(因为这个列表不会经常变化),我只需要下载数据并稍后对这些数据执行其他操作..

【问题讨论】:

【参考方案1】:

Firebase 是异步的,因此要使代码按定义的顺序执行,您需要“等待”firebase 返回数据。

Firebase 函数附带的闭包就是这样做的 - 闭包中的代码在数据(快照)有效时执行。

将 doSomethingHere() 移动到 Firebase 闭包中,它将以正确的顺序执行 - 在这种情况下

if listOfTags.count != 0 
    for tag in listOfTags 

        ref.child("tags").child(tag).observeSingleEvent(of: .value, with:  (snapshot) in

            if let temp = snapshot.children.allObjects as? [FIRDataSnapshot] 
                for elem in temp 
                    outputArray.append(elem.key)
                
                doSomethingHere() //array is populated at this point
            
        )
    

请注意,您也可以删除它

if listOfTags.count != 0

如果 listOfTags 为 0,则 for 循环不会执行。

【讨论】:

以上是关于如何仅在从 Firebase 下载数据后执行操作的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 Firebase Auth 仅在刷新后工作?

我的应用在 iOS 4.3 上崩溃,但仅在从 App Store 下载时

仅在 Swift 中随机播放结构的一部分

如何仅在 Firebase 中获取子密钥

STM32F030F4P6 仅在从闪存启动时运行中断处理程序。从引导加载程序启动时重置

Firebase 下载/上传完成后进行 Segue