简体   繁体   中英

Type 'QuerySnapshot?' has no member 'documents'

I am trying to get data back from the Firebase Firestore but have come in to one or maybe more problems

Here is my code

I a trying to get a specific document with the id of the current user id

import SwiftUI
import Firebase
import FirebaseFirestore
import FirebaseFirestoreSwift


class UsersModel: ObservableObject {
    
    @Published var userData = [UserData]()
    
    let userID = Auth.auth().currentUser!.uid
    
    private var db = Firestore.firestore()
    
    func fetchData() {
            
            db.collection("users").document(userID).addSnapshotListener { (querySnapshot, error) in
                guard let document = QuerySnapshot?.documents() else {
                    print("No documents")
                    return
                }
                
                self.userData = document.compactMap{(QueryDocumentSnapshot) -> UserData? in
                    return try? QueryDocumentSnapshot.data(as: UserData.self)
                }
            }
        }
}

but on this line guard let document = QuerySnapshot?.documents() else { I get this error Type 'QuerySnapshot?' has no member 'documents' Type 'QuerySnapshot?' has no member 'documents'

I am using the Coddle protocol

Here is my UserData

import SwiftUI
import FirebaseFirestoreSwift

struct UserData: Identifiable, Codable {
    @DocumentID var id: String?
    var username: String
    var ImageURl: URL
}

What am I doing wrong and how can I fix this please

Many Thanks for your help

Your snapshot is already a document so you can't query for 'documents' because it's not a collection

All you need to do is get your query snapshot from the listener closure, [querySnapshot] and get it's data like so:

func fetchData() {    
    db.collection("users").document(userID).addSnapshotListener { (documentSnapshot, error) in
        guard let document = documentSnapshot?.data() else {
            print("No documents")
            return
        }
        
        self.userData = document.compactMap{(QueryDocumentSnapshot) -> UserData? in
            return try? QueryDocumentSnapshot.data(as: UserData.self)
        }
    }
}

It appears you are attempting to read in a single user's data, which would be a single document. No reason to addSnapshotListener unless you want to be notified of changes.

Also, there's no reason to .compactMap because the users data can be directly read from the document.

There are many options for reading a single document and mapping it to an object; here's two:

Here's a simplifed object

struct UserData: Identifiable, Codable {
    @DocumentID var id: String?
    var username: String
    var ImageUrl: String
}

Option 1 to read the user using getDocument { (document, error) and then casting the document to a User object after being read

func readUser() {
    let userID = "uid_0"
    let docRef = self.db.collection("users").document(userID)

    docRef.getDocument { (document, error) in
        if let err = error {
            print(err.localizedDescription)
            return
        }

        if let doc = document {
            let user = try! doc.data(as: UserData.self)
            print(user.username, user.ImageUrl)
        }
    }
}

and then the second, super simple (and way cooler) option to map the users data to the user object when it's read in

func readUser2() {
    let userID = "uid_0"
    let docRef = self.db.collection("users").document(userID)

    docRef.getDocument(as: UserData.self, completion: { result in
        switch result {
        case .success(let user):
            print(user.username, user.ImageUrl)
        case .failure(let error):
            print(error.localizedDescription)
        }
    })
}

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