Abenezer Bayeh
Abenezer Bayeh

Reputation: 95

@FirestoreQuery is not returning any information

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

Answers (2)

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

Mike Parkin
Mike Parkin

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

Related Questions