简体   繁体   中英

How to read items from Cloud Firestore and write them inside list in Swift?

my question will be simple.

At this moment i can freely add items to my Cloud Firestore DB, but im not sure how to read them properly and because of it I can't load them into my list in my swift application.

Soo, the write code looks like this:

@IBAction func addItemButtonTouched(_ sender: Any) {
        let itemName = itemNameField.text!;
        
        let db = Firestore.firestore()
        
        db.collection("recipes").addDocument(data: ["name": itemName, "uid": Auth.auth().currentUser!.uid]);
    }

And my attempt to read and add item to my list inside app:

override func viewDidLoad() {
        super.viewDidLoad()

        let db = Firestore.firestore()
        
        db.collection("recipes").whereField("uid", isEqualTo: Auth.auth().currentUser!.uid).getDocuments() { (querySnapshot, err) in
            if let err = err {
                //error
            } else {
                for document in querySnapshot!.documents {
                    elements.append(Element(name: document)) // <- there is a problem
                }
            }
        }
        
}

Im not sure how to read name from my document, if I trying document.name... I getting an error:

Value of type 'QueryDocumentSnapshot' has no member 'name'.

Maybe somebody know the way how to assign data from DB to my list in app?

Update 1

Ok. Now it can be compiled, but I still don't see a new item with added label. It is visible in DB, but not in app.

Database: 数据库

App: 应用程序

And a code behind it (loading):

override func viewDidLoad() {
        super.viewDidLoad()

        let db = Firestore.firestore()
        
        db.collection("recipes").whereField("uid", isEqualTo: Auth.auth().currentUser!.uid).getDocuments() { (snapshot, err) in
            if let snapshot = snapshot {
                for doc in snapshot.documents {
                    if let itemName = doc.get("name") as? String {
                        self.elements.append(Element(name: itemName))
                    }
                }
            } else {
                if let err = err {
                    print(err)
                }
            }
        }
    }

It should show items added by me. elements.append(Element(name: "Me can exist")) <- it working fine

First, I would consider reformatting your write code without all of that forced unwrapping:

@IBAction func addItemButtonTouched(_ sender: Any) {
    guard let uid = Auth.auth().currentUser?.uid,
        let name = itemNameField.text else {
            return // return control to the caller or do something else to indicate access denied
    }
    Firestore.firestore().collection("recipes").addDocument(data: ["name": name, "uid": uid]);
}

And I would get in the habit of this very early and offer alternatives to nil values other than crashing the entire app. To read data, I'd recommend using the document snapshot's get() method:

var elements = [String]()

override func viewDidLoad() {
    super.viewDidLoad()
    Firestore.firestore().collection("recipes").whereField("uid", isEqualTo: Auth.auth().currentUser!.uid).getDocuments() { (snapshot, err) in
        if let snapshot = snapshot {
            for doc in snapshot.documents {
                if let name = doc.get("name") as? String {
                    elements.append(name)
                }
            }
            self.tableView.reloadData() // reload the UI
        } else {
            if let err = err {
                print(err)
            }
            // handle the error gracefully
            // never force unwrap Firestore's snapshots because
            // there is no guarantee that everything came in neatly
            // which is the case when dealing with any network
            // process with any API, not just Firestore
        }
    }
}

Some people choose to access the raw data of a document snapshot using data() and then getting values from the [String: Any] dictionary but I consider the get() method a cleaner interface.

NOTE: This code does not parse your data in a background queue (thread). Firestore returns on the main queue (thread). Also, there is a strong reference to the table view inside the return closure, so you may consider weakening self in your capture list:

Firestore.firestore().collection("recipes").whereField("uid", isEqualTo: Auth.auth().currentUser!.uid).getDocuments() { [weak self] (snapshot, err) in

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM