Firebase 引用对象不会保存到 SwiftUI 中的变量

Posted

技术标签:

【中文标题】Firebase 引用对象不会保存到 SwiftUI 中的变量【英文标题】:Firebase reference object doesn't save to variable in SwiftUI 【发布时间】:2020-09-10 02:46:50 【问题描述】:

我将数据存储在 Firebase 中,并且我找到了一种方法来创建仅包含键的数组。第一个打印语句正确打印出数组。但是,在数据库引用之外,变量 listOfBannedNames 似乎没有保存数组。该数组打印为 [] ,其中没有任何键。我想将数组存储在变量 listOfBannedNames 中以备后用。

    let username = username
    let formattedUsername = formatUsername(username: username)
    var listOfBannedNames = [String]()
    ref.observeSingleEvent(of: .value, with: 
        snapshot in
        var bannedNamesList = [String]()
        for bannedNames in snapshot.children 
            bannedNamesList.append((bannedNames as AnyObject).key)
        
        listOfBannedNames = bannedNamesList
        print(listOfBannedNames)
    )
    print(listOfBannedNames)

【问题讨论】:

上下文不清楚,但它与异步行为有关。第二次打印在observeSingleEvent 调用后立即调用,但不是在它完成后调用(因为此函数立即退出并且请求在后台工作)。当然,您必须将listOfBannedNames 设为所有者的财产。 @Eduard 给出了一个很好的答案。但是,更大的问题是由您的评论引发的检查用户输入的名称是否在禁止名称列表中 - 如果您想检查用户输入的名称是否在该列表中,那么为什么不直接查询 Firebase 的名称,而不是加载整个列表并在代码中处理它? 你能指导我到哪里可以找到这样做的吗? 当然。我担心的是,随着禁止名称列表的增长,例如可能是 1000 万个,加载所有要处理的名称会产生很大的开销。询问 Firebase 是否匹配要简单得多。该过程称为查询(或过滤器),并在入门指南Working With lists 的Filtering Data 部分中介绍。回复 cmets 时,在名称前加上 at 符号,例如 @Jay。然后我会收到您的回复通知。 【参考方案1】:

这正是异步行为。尝试进行以下操作:

func makeRequestToFirebase(completion: @escaping ([String]) -> Void) 
    ref.observeSingleEvent(of: .value, with: 
        snapshot in
        var bannedNamesList = [String]()
        for bannedNames in snapshot.children 
            bannedNamesList.append((bannedNames as AnyObject).key)
        
        listOfBannedNames = bannedNamesList
        print(listOfBannedNames)
        completion(listOfBannedNames) // - that will wait until the list of names arrives
    )

然后使用函数:

makeRequestToFirebase()  names in
    print(names)
    workWithNames(names)

现在你可以随心所欲地使用它,例如:

func workWithNames(names: [String]) 
    for name in names 
        if name == "Alexander" 
            print("One more Alexander found")
        

另外请了解更多关于escaping closures in Swift的信息。

【讨论】:

感谢您的回复。我似乎仍然遇到无法在 makeRequestToFirebase 之外引用 listOfBannedNames 的问题,因为我想将该列表用于 if 语句。 @kj15 没问题。我已经为你扩展了我的答案。 有没有办法可以将数组返回给另一个函数? @kj15 什么意思? ContentView 中有一个函数调用,用于检查用户输入的姓名是否在禁止姓名列表中。然后该函数检查名称并返回一个布尔值。

以上是关于Firebase 引用对象不会保存到 SwiftUI 中的变量的主要内容,如果未能解决你的问题,请参考以下文章

将对象保存到 Firebase

Firebase 不会创建新用户

如何在没有 Geofire 的情况下将位置对象保存在 Firebase 中?

将复杂的结构保存到 firebase

Firebase 数据结构,订阅引用的对象

Firebase 图像大小调整扩展。引用调整大小的图像