将Firestore文档的值分配给变量

时间:2018-08-09 12:39:59

标签: swift firebase google-cloud-firestore

我正在尝试读取Firestore文档的值。我尝试了两种不同的方法,但是每种方法都失败了。 在第一个错误中,在返回行Unexpected non-void return value in void function上引发了错误。我找出了发生这种情况的原因,因此,我采用了第二种方法。

import UIKit
import Firestore

func readAvailableLists(forUser user: String) -> [String] {
    let db = Firestore.firestore()
    db.collection("userslist").document(user).getDocument { (document, err) in
        if let document = document, document.exists {
            return UserInformationDocument(dictionary: document.data()!)?.lists!
        } else {
            print("Document does not exist")
        }
    }
}

在第二种方法中,我将UserInformationDocument(dictionary: document.data()!)?.lists!分配给一个变量,并在函数末尾返回该变量(请参见下面的代码)。但是,当我这样做时,该函数将返回一个空数组。让我惊讶的是,打印返回了正确的值,但是在函数执行了return语句后不久。是否因为它是异步需求?如果是这样,我应该如何解决?

import UIKit
import Firestore

func readAvailableLists(forUser user: String) -> [String] {
    let db = Firestore.firestore()
    var firestoreUserDocument: [String] = []
    db.collection("userslist").document(user).getDocument { (document, err) in
        if let document = document, document.exists {
            firestoreUserDocument = (UserInformationDocument(dictionary: document.data()!)?.lists!)!
        print((UserInformationDocument(dictionary: document.data()!)?.lists!)!)
        } else {
            print("Document does not exist")
        }
    }
    return firestoreUserDocument
}

1 个答案:

答案 0 :(得分:1)

Firebase调用是一个异步函数。由于它正在与服务器通信(如您所述),因此需要花费额外的时间执行-结果,完成块(在您的示例中定义documenterr的块)发生在不同的时间,身体其余部位的功能不同。这意味着您不能从其内部返回一个值,但可以将另一个闭包传递给它,以便稍后执行。这称为补全块

func readAvailableLists(forUser user: String, completion: @escaping ([String]?, Error?) -> Void) -> [String] {
    let db = Firestore.firestore()
    db.collection("userslist").document(user).getDocument { (document, err) in
        if let document = document, document.exists {
            // We got a document from Firebase. It'd be better to
            // handle the initialization gracefully and report an Error
            // instead of force unwrapping with !
            let strings = (UserInformationDocument(dictionary: document.data()!)?.lists!)!
            completion(strings, nil)
        } else if let error = error {
            // Firebase error ie no internet
            completion(nil, error)
        }
        else { 
            // No error but no document found either
            completion(nil, nil)
        }
    }
}

然后您可以这样在代码的其他位置调用此函数:

readAvailableLists(forUser: "MyUser", completion: { strings, error in
    if let strings = strings {
        // do stuff with your strings
    }
    else if let error = error {
        // you got an error
    }
})