0

I need to fetch some data from Firestore, process them, and present them to a view.

The data should reflect any changes in Firestore (say I alter a value).

I am pretty sure I need to attach a snapshotListener for this (getDocuments() method will not cut it).

Today I found out about @FirestoreQuery property wrapper (which is very helpful) but I need to find a way to make this work asynchronously.

Before fixing my code I used getDocuments(...) and I could easily use the async await like so:

func fetchAllItems() async throws -> [Item] {
    let snapshot = try await Firestore.firestore().collection("items").getDocuments()

    return snapshot.documents.compactMap { document in
        try? document.data(as: Item.self)
    }
}

Inside the View, I use the following:

.onAppear {
    Task.init {
        self.items = try await fetchAllItems()
    }
}

The code above worked just fine, but I couldn't see the changes on my app, unless I reloaded the app to force calling Firestore again.

Is there a way to replicate this but with either addSnapshotListener or @FirestoreQuery?

Can this be marked as try await or is it any other way to wait for the data to download? Cause if I use it as below, it returns an empty array:

@FirestoreQuery(collectionPath: "items") var items: [Item]

Edit: Code samples

import Foundation
import FirebaseFirestore
import FirebaseFirestoreSwift

extension Firestore {

    func fetchAllItems() async throws -> [Item] {
        let snapshot = try await Firestore.firestore().collection("items").getDocuments()

        return snapshot.documents.compactMap { document in
            try? document.data(as: Item.self)
        }
    }
}

Then inside my View:

import SwiftUI
import FirebaseFirestore

.
.

@State var allItems: [Item] = []

.onAppear {
        Task.init {
            self.allItems = try await Firestore.firestore().fetchAllItems()
        }
    }

Above code will work and receive data from Firestore just fine.

If I remove the async/await nature and go with the @FirestoreQuery then it will not receive the data (I assume that it has to do with the View loading faster than receiving the data from Firestore).

Thank you in advance!

[I am using SwiftUI]

christostsang
  • 1,701
  • 3
  • 27
  • 46

0 Answers0