【问题标题】:Turning a firebase database value into a variable Swift将 firebase 数据库值转换为 Swift 变量
【发布时间】:2020-12-04 02:43:08
【问题描述】:

我声明了一个 var,我可以从 Firebase 数据库中检索该值,但是当我在 ViewDidLoad 中打印该 var 时,它是空的,我不明白出了什么问题。感谢大家 这是我打印 var 时得到的答案:这是语言

//
var language: String = ""

//
func getUserLanguage(completion:((String) -> Void)?) {
    let ref = Database.database().reference()
    let uid = Auth.auth().currentUser!.uid
    ref.child("users").child(uid).observe(.value, with: { (snapshot) in
       let value = snapshot.value as? NSDictionary
       let languageResult = value?["language"] as? String ?? ""
       completion?(languageResult)
    }
)}

//
getUserLanguage { (languageResult) in
   self.language = languageResult
}

// I print the value in ViewDidload
print("this is the language\(self.language)")

【问题讨论】:

  • 当解包失败时,当你用value?["language"] as? String ?? "" 分配空字符串时,你怎么会得到零?并尝试使用[String: Any] 而不是NSDictionary 并检查快照是否实际返回该值。
  • 快照返回值但只在函数内部,当我在这个函数以外的任何地方调用var时,它是= nil
  • var language: String = "" 不是可选的。您永远无法将其值设为nil。如果您在viewDidLoad 中调用getUserLanguage 并尝试在调用完成之前访问它,您将得到一个空字符串。您可以添加有问题的快照值吗?
  • 对不起,我不明白我应该做什么,快照值应该是“英语”
  • 您能否在您的问题中添加打印的快照值?

标签: swift database firebase var


【解决方案1】:
  1. 尝试在函数中打印languageResult - 也许你没有在函数内部得到它并且变量没有被赋值
  2. 公开language变量

【讨论】:

  • 公开 var 并没有太大变化。该函数有效,其中正确的值是从 Firebase 检索的,当我尝试在其他地方使用该变量时,它的值尚未更新
【解决方案2】:

我认为您在这里缺少代码的异步特性。 getUserLanguage 函数只有在从 firebase 的 observe(.value, with: { (snapshot) 方法获得回调时才会调用完成。它是异步的。在viewDidLoad 中调用getUserLanguage 后,您不会立即获得language 的值。

override func viewDidLoad() {
    super.viewDidLoad()
    
    getUserLanguage { (language) in
        print(language) // --> prints the expected value
        self.language = language
    }
    print(language) // --> prints ""
}

func getUserLanguage(completion: @escaping (String) -> Void) {
    let ref = Database.database().reference()
    let uid = Auth.auth().currentUser!.uid
    ref.child("users").child(uid).observe(.value, with: { (snapshot) in
        let value = snapshot.value as? [String: Any]

        let languageResult = value?["language"] as? String ?? ""
        print("language: ", languageResult) // --> prints the expected value

        completion(languageResult)
    })
}

【讨论】:

  • 那我该如何解决这个问题?我希望能够将我从 Firebase 中检索到的带有快照的值转换为变量
  • 您可以使用变量language,但只有在getUserLanguage 中调用完成闭包后才会设置其值。请检查我在哪里设置了 self.language。如果您想在 viewDidLoad 本身内部对其进行操作,请在该行之后执行。之后你可以对这个变量做任何你想做的事情。
  • 是的,但是例如在 ViewDidLoad() 中调用 getUserLanguage 之后的 print(language) 返回空,所以我不能使用getUserLanguage 之外的变量,为什么只在函数内部更新了变量?
  • 请阅读这篇文章:stackoverflow.com/a/46245943/5443937 并尝试使用闭包/完成处理程序
  • 对不起,我已经阅读了这篇文章并尝试将其实现到我的代码中,但似乎没有任何效果,我不知道该怎么办了
猜你喜欢
  • 1970-01-01
  • 2017-02-24
  • 2018-04-08
  • 2017-07-30
  • 2017-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多