从 Firebase 检索数据等于意外 nil - swift

Posted

技术标签:

【中文标题】从 Firebase 检索数据等于意外 nil - swift【英文标题】:Retrieving data from Firebase equals unexpected nil - swift 【发布时间】:2016-11-24 13:59:04 【问题描述】:

我遇到了最奇怪的错误,我不知道如何解决它.. 我有一个 Firebase 数据库,其中包含所有来自用户的帖子。它们存储在feed-items 下。每当用户发布新帖子时,该帖子都会添加到 feed-items,并且 feed-items 中帖子的键(autoId)会添加到用户拥有的每个关注者。

如果我在我的 UITableView 中显示来自 feed-items 的所有帖子,那么根本没有问题。如果我尝试显示与存储在用户个人墙中的密钥相同的帖子(当我关注的用户发布帖子时添加的密钥),那么我会在我的Sweet 中收到一个奇怪的错误unexpectedly found nil while unwrapping an optional结构?

让我先给你看两个代码,一个有效,另一个无效:

工作代码:

func observePosts(userID: String) 
//        let ref = FIRDatabase.database().reference().child("Users").child(userID).child("Wall")
//        ref.observeEventType(.ChildAdded, withBlock:  (snapshot) in
//            
//            let postId = snapshot.key
            let postReference = FIRDatabase.database().reference().child("feed-items")//.child(postId)

            postReference.observeSingleEventOfType(.Value, withBlock:  (snapshot) in
                print(snapshot)
                var newUpdates = [Sweet]()
                    for update in snapshot.children 
                        let postUpdates = Sweet(snapshot: update as! FIRDataSnapshot)
                        newUpdates.append(postUpdates)
                    
                    self.updates = newUpdates.reverse()

                    dispatch_async(dispatch_get_main_queue(), 
                       self.tableView.reloadData()
                    )
                , withCancelBlock: nil)
            //, withCancelBlock: nil)
    

代码无效:

func observePosts(userID: String) 
        let ref = FIRDatabase.database().reference().child("Users").child(userID).child("Wall")
        ref.observeEventType(.ChildAdded, withBlock:  (snapshot) in

            let postId = snapshot.key
            let postReference = FIRDatabase.database().reference().child("feed-items").child(postId)

            postReference.observeSingleEventOfType(.Value, withBlock:  (snapshot) in
                print(snapshot)
                var newUpdates = [Sweet]()
                    for update in snapshot.children 
                        let postUpdates = Sweet(snapshot: update as! FIRDataSnapshot)
                        newUpdates.append(postUpdates)
                    

                    self.updates = newUpdates.reverse()

                    dispatch_async(dispatch_get_main_queue(), 
                       self.tableView.reloadData()
                    )
                , withCancelBlock: nil)
            , withCancelBlock: nil)
    

应用程序崩溃的地方,我得到错误的那一行在我的结构中,在 likesForPost 下

我的结构

import Foundation
import FirebaseDatabase
import FirebaseAuth
import UIKit

struct Sweet 
    let key: String!
    let content: String!
    let addedByUser: String!
    let profilePhoto: String!
    var likesForPost : [String:AnyObject]
    let itemRef: FIRDatabaseReference?
    let path : String!
    let date: String!
    let category: Int!
    let workoutComment: String!
    let workoutTime: String!


    init (content: String, addedByUser: String, profilePhoto: String!, likesForPost : [String:AnyObject]!, date: String, category: Int, workoutComment: String, workoutTime: String, key: String = "") 
        self.key = key
        self.content = content
        self.addedByUser = addedByUser
        self.profilePhoto = profilePhoto
        self.likesForPost = likesForPost
        self.itemRef = nil
        // self.path = dataPath
        self.path = ""
        self.date = date
        self.category = category
        self.Comment = Comment
        self.Time = Time
    

    init (snapshot: FIRDataSnapshot) 
        key = snapshot.key
        itemRef = snapshot.ref
        path  = key
        if let theFeedContent = snapshot.value!["content"] as? String 
            content = theFeedContent
         else 
            content = ""
        

        if let feedUser = snapshot.value!["addedByUser"] as? String 
            addedByUser = feedUser
         else 
            addedByUser = ""
        

        if let feedPhoto = snapshot.value!["profilePhoto"] as? String! 
            profilePhoto = feedPhoto
         else 
            profilePhoto = ""
        

        if let feedLikes = snapshot.value!["likesForPost"] as? [String:AnyObject]! 
            likesForPost = feedLikes
         else 
            likesForPost = ["":""]
        

        if let feedDate = snapshot.value!["date"] as? String! 
            date = feedDate
         else 
            date = ""
        

        if let feedCategory = snapshot.value!["category"] as? Int! 
            category = feedCategory
         else 
            category = 0
        

        if let feedComment = snapshot.value!["Comment"] as? String! 
            Comment = feedComment
         else 
            Comment = ""
        

        if let feedTime = snapshot.value!["Time"] as? String! 
            Time = feedTime
         else 
            Time = ""
        

    

    func toAnyObject() -> AnyObject 
        return ["content":content, "addedByUser":addedByUser, "profilePhoto":profilePhoto!, "likesForPost":likesForPost, "date":date, "category":category, "Comment":Comment, "Time":Time]
    

我知道这是一篇很长的帖子,但如果你能花时间帮助我,我会很高兴 - 我完全迷失了! :(

编辑: 这是日志给我的:

Snap (-KXLGyWMljc2UNeRL1a3) 
    addedByUser = "Maja P";
    category = 1;
    content = Hejehjehj;
    date = "Nov,24,,2016,,1:20";
    likesForPost =     
        "user id" = 0;
    ;
    profilePhoto = VGpbOweP4jO2seeLNCGiv1p08jq1;
    Comment = "";
    Time = "";

fatal error: unexpectedly found nil while unwrapping an Optional value

这是完全正确的,但是有两篇文章只打印了上面的一篇。

【问题讨论】:

结构中的所有! 都是潜在问题。您是否需要使用隐式展开的选项?如果它们是nil,则取消引用其中任何一个都可能导致崩溃。 它们都不应该是零,这是我不明白的 - 正如您在我的问题底部看到的那样,输出值都不是零? @sbooth 【参考方案1】:

由于在第二个代码中您直接获得了帖子的DataSnapshot,我认为您不需要迭代snapshot

试着把你的代码改成这个,看看能不能用。

func observePosts(userID: String) 
    let ref = FIRDatabase.database().reference().child("Users").child(userID).child("Wall")
    ref.observeEventType(.ChildAdded, withBlock:  (snapshot) in

        let postId = snapshot.key
        let postReference = FIRDatabase.database().reference().child("feed-items").child(postId)

        postReference.observeSingleEventOfType(.Value, withBlock:  (snapshot) in
            print(snapshot)
                let update = Sweet(snapshot: snapshot)
                self.updates.insert(update, atIndex: 0)

                dispatch_async(dispatch_get_main_queue(), 
                   self.tableView.reloadData()
                )

            , withCancelBlock: nil)

        , withCancelBlock: nil)

【讨论】:

太棒了!我找这个很久了!非常感谢 :-) 你知道我可以如何扭转self.updates 吗?如果我这样做 self.updates.reverse() 它说它没有被使用并且什么都没有发生:( 我猜你正在使用 Swift 2,在这种情况下写 self.updates = self.updates.reverse() 来反转你的数组。 像魅力一样工作!

以上是关于从 Firebase 检索数据等于意外 nil - swift的主要内容,如果未能解决你的问题,请参考以下文章

读取 Firebase 数据:线程 1:致命错误:在展开可选值时意外发现 nil

URL 错误:在展开可选值时意外发现 nil:文件

如何防止致命错误:在展开可选值时意外发现 nil

我无法从 Firestore Flutter 检索和查看数据

ParseSwift SDK 中的 ParseKeyValueStore,backingStore 意外发现 nil

使用 NSFileManager 检索多个值时收到“致命错误:在展开可选值时意外发现 nil”