尝试读取我的数据库用户详细信息,它会作为可选值打印出来

Posted

技术标签:

【中文标题】尝试读取我的数据库用户详细信息,它会作为可选值打印出来【英文标题】:Trying to read my database users details it prints out as an optional value 【发布时间】:2017-03-15 12:10:26 【问题描述】:

尝试从 firebase 检索用户并且无法说明返回可选值的错误,代码已附在下面。 我也在下面添加了调试器消息。

代码

var ref = FIRDatabaseReference.init()

@IBOutlet weak var points: UILabel!
@IBOutlet weak var currentUser: UILabel!

override func viewDidLoad() 
    super.viewDidLoad()
    ref = FIRDatabase.database().reference()


func setupProfile()
    let uid = FIRAuth.auth()?.currentUser?.uid
    let ref = FIRDatabase.database().reference().child("users").child(uid!)
    ref.observeSingleEvent(of: .value, with:  snapshot in

    if let dictionary = snapshot.value as? [String: AnyObject] 

            let username1 = dictionary["username"] as! String
            print(username1)
            self.username.text = username1//Error is caused on this line EXC_BAD_Instruction
            //   ( code= EXC_I386_INVOP,subcode = 0x0)

         

    )

自动委托代理。要禁用代理,请在 Info.plist Snap (fpzfqMTapNel8F90q8bEO450eYg1) 中将标志 FirebaseAppDelegateProxyEnabled 设置为 NO 电子邮件 = "abcd@test.com"; 点数 = 100; 用户名 = abcd;致命错误:在展开可选值 (lldb) 时意外发现 nil

【问题讨论】:

了解 Optional 的工作原理,这里有很好的解释:developer.apple.com/library/content/documentation/Swift/… 感谢 Eric 的快速回复,但不幸的是,我之前已经在该页面上,试图理解我在这里犯的错误。我尝试了多种方法。但它仍然显示相同的错误:( . 好的。然后让我们试着缩小你的问题的范围。我的意思是,您应该从问题中删除与它无关的代码,这样人们可能更容易看到问题所在。您还应该指出哪一行导致崩溃 - 并在调试器崩溃时检查调试器中的值是什么。 在 setupProfile 方法中为什么要放?在字符串之后?删除它并尝试 删除 ?在String仍然不起作用之后,我已经尝试过了 【参考方案1】:

回答这个问题:代码格式错误,并且在快照中的值为 nil 的情况下容易崩溃。即,这意味着,例如,您尝试访问 snapshot.value 中的键“用户名”(作为字典),但“用户名”键不存在。

这里有一些建议的代码,有两个选项

    let uid = FIRAuth.auth()?.currentUser?.uid
    let ref = FIRDatabase.database().reference().child("users").child(uid)
    ref.observeSingleEvent(of: .value, with:  snapshot in

         //make sure dict is available before proceeding
         if let dict = snapshot.value as? [String: AnyObject] 

              //this is a test in response to a comment
              let email = dictionary["email"] as! String
              print(email)
              self.user.text = email

              ///if you are sure the 'username' key will always exist (neve
              let username = dictionary["username"] as! String
              print(username)
              self.user.text = username

              //if you are unsure if the 'username' will exist or not, protect your code!
              if let username = dict["username"] as? String 
                   //do something with username
              
          

    )

为了配合 cmets,了解可选选项是使用 Swift 和保护您的代码(和用户)的关键。

还有其他选项可以保护您的代码,但请先尝试。

【讨论】:

非常感谢@Jay 的惊人响应,这里的问题是,如果我在调试器中为它分配值,它实际上会打印用户名,但是在分配 self.user.text = username例如,它给出了一个错误,指出它是一个可选值。 @ZahidAhmed 问题是这里的变量太多(不在代码中),所以我们需要隔离出问题所在。我稍微改变了答案以帮助隔离问题。试试我所做的,看看它是否仍然错误。 您所做的更改正是我在最终确定错误仍然存​​在之前所尝试的。 :( 。我不知道这里会出现什么问题。但非常感谢你帮我解决这个问题。 @ZahidAhmed 用户名是否打印并且错误出现在下一行?只要用户类对象的变量设置正确,我的答案中的代码就可以工作。 正是用户名打印,错误发生在下一行。变量也已正确设置

以上是关于尝试读取我的数据库用户详细信息,它会作为可选值打印出来的主要内容,如果未能解决你的问题,请参考以下文章

NSEntityDescription 在展开可选值时返回 nil

可选值上的 KeyPath 出现奇怪错误

如何在spring EL中将null作为可选值传递?

UIPickerView:在展开可选值时意外发现 nil

tableview reloadData在解包可选值时崩溃意外发现的nil

Firebase 数据库 - 致命错误:在展开可选值时意外发现 nil