0

I have a tableview that presents events that a user creates. When you click on one of them it takes you to a different page that presents the details of the event.

I'm using Firebase and passing the postID from the tableview to the detailed view and all the information is being passed correctly in an NSDictionary.

However, when I try to access the NSDictionary out of the viewDidLoad and in an IBAction it tells me that the NSDictionary is nil. When I check in the viewDidLoad it is not nil.

I'm very new to programming and learning along the way but I've been stuck on this for a while now and have no idea whats wrong or how I can fix it

this is my code

import UIKit
import Firebase

class BeehiveViewViewController: UIViewController {



    @IBOutlet weak var eventImage: UIImageView!
    @IBOutlet weak var eventName: UILabel!
    @IBOutlet weak var location: UILabel!
    @IBOutlet weak var eventDate: UILabel!
    @IBOutlet weak var eventHost: UILabel!
    @IBOutlet weak var members: UILabel!
    @IBOutlet weak var joinButton: roundButton!


    var beehiveID: NSDictionary?
    var ref = Database.database().reference()


    override func viewDidLoad() {
        super.viewDidLoad()

        view.setGradientBackground(colourOne: primaryColor, colourTwo: secondaryColor)

        let uid = Auth.auth().currentUser?.uid
        ref.child("users").child(uid!).child(self.beehiveID?["pid"] as! String).observe(.value) { (snapshot) in

            let uid = self.beehiveID!["pid"] as! String
            self.beehiveID = snapshot.value as? NSDictionary
            self.beehiveID?.setValue(uid, forKey: "pid")
    }

        let imageURL = self.beehiveID!["imageDownloadURL"] as! String

        let url = URL(string: imageURL)
        DispatchQueue.global(qos: .background).async {

            let data = NSData(contentsOf: url!)
            DispatchQueue.main.async {

            self.eventImage.image = UIImage(data: data! as Data)



            }
        }

        self.eventName.text = self.beehiveID?["eventName"] as? String
        self.eventDate.text = self.beehiveID?["eventDate"] as? String
        self.eventHost.text = self.beehiveID?["beehiveHost"] as? String
        self.location.text = self.beehiveID?["location"] as? String

        let uidd = Auth.auth().currentUser?.uid
        Database.database().reference().child("users").child(uidd!).child("Posts").child(self.beehiveID?["pid"] as! String).child("Members").observe(.value) { (snapshot) in

            let memberCount = snapshot.childrenCount
            self.members.text = "\(memberCount)"
        }

        let userID = Auth.auth().currentUser?.uid
        Database.database().reference().child("users").child(userID!).child("Posts").child(self.beehiveID?["pid"] as! String).observe(.value) { (snapshot) in

            print(snapshot)

            if (snapshot.exists()){

                self.joinButton.setTitle("Remove Beehive", for: .normal)
            }

            else{

                self.joinButton.setTitle("Join Beehive", for: .normal)
            }
        }



}

    @IBAction func buttonPressed(_ sender: Any) {

        if joinButton.titleLabel?.text == "Remove Beehive"{

            let uid = Auth.auth().currentUser?.uid
            let dbref = ref.child("users").child(uid!).child("Posts").child(beehiveID?["pid"] as! String)

//error is the line above that beehiveID?["pid"] is nil

            dbref.removeValue()


            navigationController?.popViewController(animated: true)

        }

        if joinButton.titleLabel?.text == "Join Beehive"{

            let uid = Auth.auth().currentUser?.uid
            let dbref = Database.database().reference().child("users").child(uid!).child("Posts").child("Members")
            Database.database().reference().child("users").child(uid!).child("Name").observe(.value) { (nameSnapshot) in
                let memberName = nameSnapshot.value as! String
                let userObject = [memberName: uid]
                dbref.updateChildValues(userObject as! [AnyHashable : String])
            }

        }
    }

}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Data is loaded from Firebase asynchronously. If you need the data in some of your code, that should be (called from) **inside** the closure. See https://stackoverflow.com/questions/38364288/getting-data-out-of-a-closure-that-retrieves-data-from-firebase for an example. – Frank van Puffelen Oct 08 '18 at 02:39
  • 1
    Maybe a little bit off-topic, but don't use `NSDictionary` in Swift, use `Dictionary` instead. – Cristik Oct 08 '18 at 04:25

1 Answers1

0

I assume that you're passing beeHive's value from the previous controller as you haven't initialised or got the values of it anywhere:-

Try having a breakpoint right before the end of viewDidLoad to double-check if the dictionary isn't nil at the block

self.beehiveID = snapshot.value as? NSDictionary

Try using a check to see if the snapshot's value is nil using 'if let' or 'guard' as you could possibly just be assigning a nil value to the NSDictionary. Also, since you're using optionals for assigning each value, it doesn't return an exception but just keeps assigning the nil value to every property

Do try this and let me know. Glad to help!

Lokesh SN
  • 1,583
  • 7
  • 23
  • The OP is trying to access *self.beehiveID?* outside of the closure. That var will only be populated *inside* the closure so the code right after the closure will have nil values. – Jay Oct 08 '18 at 17:35