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.