-1

Premise

I am currently making SNS with Swift. I encountered the following error message while implementing user added functionality on it.

Error message

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Code Swift4

import UIKit

class PeopleViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    var users = [UserModel]()
    var userUid = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.dataSource = self
        tableView.tableFooterView = UIView(frame: .zero)
        tableView.rowHeight = 80

        loadUser()
    }

    func loadUser() {
        UserApi.shared.observeUser { (user) in
            self.isFollowing(userUid: user.uid!, completed: { (value) in
                **if user.uid != UserApi.shared.CURRENT_USER_UID! {** <-errorPoint
                    user.isFollowing = value
                    self.users.append(user)
                    self.tableView.reloadData()
                }
            })
        }
    }


    func isFollowing(userUid: String, completed: @escaping (Bool) -> Void ) {
        FollowApi.shared.isFollowing(withUser: userUid, completed: completed)

    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ShowUserInfoSegue" {
            let showUserInfoVC = segue.destination as! ShowUserinfoViewController
            showUserInfoVC.userUid = self.userUid
        }
    }
}

extension PeopleViewController: PeopleCellDelegate {

    func didTappedShowUserInfo(userUid: String) {
        self.userUid = userUid
        performSegue(withIdentifier: "ShowUserInfoSegue", sender: self)
    }
}


    extension PeopleViewController: UITableViewDataSource {

        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return users.count
        }

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "PeopleTableViewCell", for: indexPath) as! PeopleTableViewCell

            cell.user = users[indexPath.row]
            cell.delegate = self

            return cell

        }
}

Code Swift4

import Foundation
import FirebaseDatabase
import FirebaseAuth

class UserApi {
    var REF_USERS = Database.database().reference().child("users")

    static var shared: UserApi = UserApi()
    private init() {
    }

    var CURRENT_USER_UID: String? {
        if let currentUserUid = Auth.auth().currentUser?.uid {
            return currentUserUid
        }
        return nil
    }

    var CURRENT_USER: User? {
        if let currentUserUid = Auth.auth().currentUser {
            return currentUserUid
        }
        return nil
    }

        func observeUser(uid: String, completion: @escaping (UserModel) -> Void) {
            REF_USERS.child(uid).observeSingleEvent(of: .value) { (snapshot) in
                guard let dic = snapshot.value as? [String: Any] else { return }
                let newUser = UserModel(dictionary: dic)
                completion(newUser)
            }
    }

    func observeUser(completion: @escaping (UserModel) -> Void ) {
        REF_USERS.observe(.childAdded) { (snapshot) in
            guard let dic = snapshot.value as? [String: Any] else { return }
            let user = UserModel(dictionary: dic)
            completion(user)
        }
    }

    func observeCurrentUser(completion: @escaping (UserModel) -> Void ) {
        guard let currentUserUid = CURRENT_USER_UID else { return }
        REF_USERS.child(currentUserUid).observeSingleEvent(of: .value) { (snapshot) in
            guard let dic = snapshot.value as? [String: Any] else { return }
            let currentUser = UserModel(dictionary: dic)
            completion(currentUser)
        }
    }

    func queryUser(withText text: String, completion: @escaping(UserModel) -> Void ) {
        REF_USERS.queryOrdered(byChild: "username_lowercase").queryStarting(atValue: text).queryEnding(atValue: text + "\u{f8ff}").queryLimited(toLast: 5).observeSingleEvent(of: .value) { (snapshot) in
            snapshot.children.forEach({ (data) in
                let child = data as! DataSnapshot
                guard let dic = child.value as? [String: Any] else { return }
                let user = UserModel(dictionary: dic)
                completion(user)
            })
        }
    }
}

What I tried

How can I fix "Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value" in Swift

https://learnappmaking.com/found-nil-while-unwrapping-optional-value/

I browsed and examined these sites, but it did not work. I think that user information can not be taken out successfully.

Supplementary information

We will add additional information if we have other missing information. Since I often do not understand Swift in 3 weeks, I would like you to tell me with concrete code etc. Also, I am happy if you can tell me the cause of the error.

FW / tool version

Takuya
  • 29
  • 4
  • This mainly happens because you are force unwrapping optionals. Check where you have done this. – kathayatnk Aug 11 '18 at 08:51
  • Possible duplicate of [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?](https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – Cristik Aug 11 '18 at 09:08
  • thanks!!!I think my uid or isfollowing may be wrong since it causes error. – Takuya Aug 13 '18 at 08:04

1 Answers1

2

You're trying to access the CURRENT_USER_UID from UserApi Singleton class which is Optional computed property which seems to be returning nil. If there's not current user signed-in than Firebase Auth returns nil instead of uid

Auth.auth().currentUser?.uid // Because of Optional Chaining  

I'd Suggest you to safely unwrap Optionals.

func loadUser() {
    UserApi.shared.observeUser { (user) in
        self.isFollowing(userUid: user.uid!, completed: { (value) in

        if let currentUser = UserApi.shared.CURRENT_USER_UID {

              if user.uid != currentUser {
                user.isFollowing = value
                self.users.append(user)
                self.tableView.reloadData()
            }
        } else {
               // Current user not Signed-In
            }

        })
    }
}
Tushar Katyal
  • 412
  • 5
  • 12