Putte
Putte

Reputation: 328

Insert Firestore data into pickerview

Thread is solved after I got help from the comments.

I saw another thread about this, but it didn't helped me after hours of tries. So I'd no choice of creating a new thread. (Sorry for that)

In the beginning of the class I've this:

//Firestore connection
let db = Firestore.firestore()

//Create an array of items to insert into pickerview
var dogsArray: [String] = []

Inside the ViewDidLoad I've Delegate and Datasource for the pickerview.

    override func viewDidLoad()
{
    super.viewDidLoad()

    getDogs()


    self.pickerView.delegate = self
    self.pickerView.dataSource = self

}

And a little bit down, I got this code:

func numberOfComponents(in pickerView: UIPickerView) -> Int
    {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
    {
        return dogsArray[row]
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
    {
        return dogsArray.count
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
    {
        labeltest.text = dogsArray[row]
    }

    func getDogs()
{
    db.collection("Dogs").getDocuments
        { (QuerySnapshot, err) in
            if err != nil
            {
                print("Error getting documents: \(String(describing: err))");
            }
            else
            {
                for document in QuerySnapshot!.documents
                {
          let document = QuerySnapshot!.documents.first
                    let data = document!.data()
                    data.forEach { (item) in
                        if let dogOneData = data["Dog1"] as? String {
                            self.dogsArray.append(dogOneData)
                        }

                        if let dogTwoData = data["Dog2"] as? String {
                            self.dogsArray.append(dogTwoData)
                        }

                        if let dogThreeData = data["Dog3"] as? String {
                            self.dogsArray.append(dogThreeData)
                        }

                }
                    self.pickerView.reloadAllComponents()
            }
    }
}

Error: Cannot convert value of type 'Any?' to closure result type 'String?' on the return (dogElement.value as? [String: Any])?.values.first

So I'm trying to select data from Firestore and insert it into a pickerview. But the data I want to select is data I entered when registered on the application. So everyone's is unique. (Ex. If you register on the app, your dog names is different from mine.)

So I'm trying to select data from a specific user. But I've no idea how to do. And the result is blank at the moment, I cannot see any data at all in the pickerview. So, I'd love to get some help on this! You would make my Friday be a good one. :)

Database structure: structure


RESULT AFTER SOLVED:

//Function getDogs()
func getDogs()
{
    //Authentication
    let authentication = Auth.auth().currentUser?.uid

    //Choosing collection
    db.collection("users").document(authentication!).collection("Dogs").getDocuments()
        { (QuerySnapshot, err) in
            if err != nil
            {
                print("Error getting documents: \(String(describing: err))");
            }
            else
            {
                //For-loop
                for _ in QuerySnapshot!.documents
                {
                    self.dogsArray.removeAll()
                    let document = QuerySnapshot!.documents.first
                    let data = document!.data()
                    data.forEach { (item) in
                        if let dogOneData = data["Dog1"] as? String {
                            self.dogsArray.append(dogOneData)
                        }

                        if let dogTwoData = data["Dog2"] as? String {
                            self.dogsArray.append(dogTwoData)
                        }

                        if let dogThreeData = data["Dog3"] as? String {
                            self.dogsArray.append(dogThreeData)
                        }

                }
                    self.pickerView.reloadAllComponents()
            }

Upvotes: 0

Views: 300

Answers (2)

Vasilis D.
Vasilis D.

Reputation: 1456

you call getData on a delegate function and because it is unsynchronized they are not being load before the rest of the delegate functions get called.

You should first call the getData() function and then reload the PickerviewDataSource

For example on viewDidAppear() function call the

getDogs()

and add inside the getDogs() function, after the loop

    dogsArray.removeAll()
    let document = QuerySnapshot!.documents.first
        let data = document.data()
    data.forEach { (item) in
        if let dogOneData = item["Dog1"] as? String {
            dogsArray.append(dogOneData)
        }

        if let dogTwoData = item["Dog2"] as? String {
            dogsArray.append(dogTwoData)
        }

        if let dogThreeData = item["Dog3"] as? String {
            dogsArray.append(dogThreeData)
        }
    }

self.pickerView.reloadAllComponents()

Upvotes: 2

Scriptable
Scriptable

Reputation: 19750

Firstly, you shouldn't call getDogs in titleForRowcall it in viewDidLoad

Secondly, you need to call reload after the loop.

func getDogs()
    {
        db.collection("Dogs").getDocuments
            { (QuerySnapshot, err) in
                if err != nil
                {
                    print("Error getting documents: \(String(describing: err))");
                }
                else
                {
                    for document in QuerySnapshot!.documents
                    {
                        let data = document.data()
                        let dogs = data["Dogs"] as? String ?? ""

                        self.dogsArray.append(dogs)
                    }

                    DispatchQueue.main.async
                    {
                        self.pickerView.reloadAllComponents()
                    }
                }
        }
    }

Upvotes: 2

Related Questions