Reputation: 95
I'm trying to use @FirestoreQuery to fetch Firestore documents using SwiftUI app. However, for some reason it is not working at all. The same functionality works when using SnapshotListener and FetchData inside onAppear, so it is not associated with Firebase rules etc. The package dependency is up to next major. Please try to reproduce this as it seems something is broken within Firebase to prevent this. It may also be that the service is offered as Beta, but an explanation would be nice. On my end, I've attached all of the code I have, which is very basic.
Non-working one (using @FirestoreQuery)
import SwiftUI
import Firebase
import FirebaseAuth
import FirebaseFirestore
import FirebaseFirestoreSwift
struct ContentView: View {
@FirestoreQuery(collectionPath: "todos") var todos: [Todo]
var body: some View {
List(self.todos) { todo in
Text(todo.title)
.foregroundColor(Color.white)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Todo : Identifiable, Decodable {
var id = UUID()
var title: String
var done: Bool
}
Working one (SnapshotListener)
import SwiftUI
import Firebase
import FirebaseAuth
import FirebaseFirestore
import FirebaseFirestoreSwift
struct ContentView: View {
@ObservedObject var todos = getTodosData()
var body: some View {
List(self.todos.datas) { todo in
Text(todo.title)
.foregroundColor(Color.white)
}
.onAppear{
self.todos.retrieveData()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Todo : Identifiable, Decodable {
var id = UUID()
var title: String
var done: Bool
}
class getTodosData : ObservableObject{
@Published var datas = [Todo]()
private var db = Firestore.firestore()
func retrieveData(){
db.collection("todos").addSnapshotListener{ (querySnapshot, error) in
guard let mov = querySnapshot?.documents else{
print("No todo")
return
}
self.datas = mov.map{(queryDocumentSnapshot) -> Todo in
let data = queryDocumentSnapshot.data()
let id = UUID()
let title = data["title"] as? String ?? ""
let done = data["done"] as? Bool ?? false
return Todo(id: id, title: title, done: done)
}
}
}
}
Upvotes: 2
Views: 313
Reputation: 11
use @DocumentID var id: String? instead "var\let id = UUID()" and then you can use var's in your struct
struct Todo : Identifiable, Decodable {
@DocumentID var id: String?
let/var title: String
let/var done: Bool
}
Upvotes: 1
Reputation: 38
Maybe a bit late, but after struggling with this for too long I finally figured out the solution. So, I thought I should share it for anyone who might need it.
In your Todo struct you declare your variables with var, but the @FirestoreQuery wrapper requires variables be declared with let.
struct Todo : Identifiable, Decodable {
let id = UUID()
let title: String
let done: Bool
}
Upvotes: 1