Christopher Davis
Christopher Davis

Reputation: 99

Issue pulling content from Firebase into Swift

enter image description here

I'm trying to get quotes out of Firebase, and I'm struggling. Granted, I also have no idea what I'm doing. I could use some help!

In Firebase, my quotes are set up like :

root --> quotes --> quoteID --> quoteText, quoteAttribution

I'm trying to pull quotes down from Firebase, add them to a local array (to later put in a dictionary), and then pull a random one to use in the app. I hope to put the quoteText into quoteLabel.text, and the quoteAttribution into authorLabel.text. I found this solution in another StackOverflow issue, but it throws the following error at line 43:

Could not cast value of type 'NSNull' (0x10f549740) to 'NSDictionary' (0x10f549178). 2018-07-21 22:49:50.241473-0400 Wavefully[72475:1126119] Could not cast value of type 'NSNull' (0x10f549740) to 'NSDictionary' (0x10f549178).

Does anyone have any tips for how I might pull quoteText and quoteAttribution out of Firebase to use in my app?


Here's my code:

class ViewController: UIViewController {

class quoteClass {
    var uid = ""
    var quote = ""
    var author = ""
}

@IBOutlet weak var quoteLabel: UILabel!
@IBOutlet weak var authorLabel: UILabel!

var ref: DatabaseReference?
var databaseHandler: DatabaseHandle?

var quotesArray = [quoteClass]()

override func viewDidLoad() {
    super.viewDidLoad()

    // Set the reference to Firebase
    ref = Database.database().reference()

    let quotesRef = ref?.child("quotes")
    quotesRef?.observeSingleEvent(of: .value, with: { (snapshot) in
        for _ in snapshot.children {
            let quoteSnap = snapshot
            let quoteKey = quoteSnap.key

            let thisQuoteRef = quotesRef?.child("quoteID")
            thisQuoteRef?.observeSingleEvent(of: .value, with: { (quoteSnap) in
                let singlequoteSnap = quoteSnap
                let quoteDict = singlequoteSnap.value as! [String:AnyObject]
                let quote = quoteDict["quoteText"]
                let author = quoteDict["quoteAttribution"]

                let aQuote = quoteClass()
                aQuote.uid = quoteKey
                aQuote.quote = quote as! String
                aQuote.author = author as! String

                print(aQuote.quote)
                print(aQuote.author)
                print(aQuote.uid)

                self.quotesArray.append(aQuote)
            })
        }
    })

    let singleQuote = quotesArray.randomItem()!
    print(singleQuote.uid)
    print(singleQuote.quote)
    print(singleQuote.author)}}

Thanks a ton for helping!

Upvotes: 0

Views: 98

Answers (2)

Dhaval Dobariya
Dhaval Dobariya

Reputation: 473

Alternatively you can also use your data by casting it into NSDictionary like below:

        let dictionary = snapshot.value as? NSDictionary
        let quote = dictionary["quoteText"] as? String ?? ""

Upvotes: 1

Christopher Davis
Christopher Davis

Reputation: 99

Okay, so I was making it way harder than it needed to be. I did this, and it's working:

func grabData() {
    ref = Database.database().reference()
    ref?.child("quotes").observe(.value, with: {
        snapshot in

        for snap in snapshot.children.allObjects as! [DataSnapshot] {

            guard let dictionary = snap.value as? [String:AnyObject] else {
                return
            }
            let quote = dictionary["quoteText"] as? String
            let author = dictionary["quoteAttribution"] as? String
            let id = dictionary["quoteID"] as? String

            self.quoteLabel.text = quote
            self.authorLabel.text = author

            print(quote!)
            print(author!)
            print(id!)
        }
    })
}

Now, I just have to call grabData() in my viewDidLoad to get a quote. Up next: randomize what quote is shown. Oh, and probably store it in Core Data or Realm for local storage. 🤓

Thanks for stopping by!

Upvotes: 0

Related Questions