仅在从Firebase

时间:2017-03-26 10:53:41

标签: swift firebase firebase-realtime-database completion

我试图弄清楚只有在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 个答案:

答案 0 :(得分:4)

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循环不会执行。