Swiftui - Show the Data Fetched from Firebase in View

SwiftUI - Show the data fetched from Firebase in view?

Looks to me like you really just want to have one user that you're pulling the data for, but you've set up your UserProfileViewModel with an array of users ([UserProfileModel]). There are a number of ways that you could take care of this. Here's one (check the code for inline comments about what is going on):

class UserProfileViewModel: ObservableObject {

@Published var user : UserProfileModel? = nil // now an optional

private var db = Firestore.firestore()

func data(){
db.collection("Users").whereField("uuidFromFirebase", isEqualTo: Auth.auth().currentUser!.uid).addSnapshotListener { (snapshot, error) in
guard let documents = snapshot?.documents else {
print("No Documents")

return
}

self.user = documents.compactMap { queryDocumentSnapshot -> UserProfileModel? in

return try? queryDocumentSnapshot.data(as: UserProfileModel.self)
}.first // Take the first document (since there probably should be only one anyway)
}
}
}
struct MainView: View {

@ObservedObject private var viewModel = UserProfileViewModel()

var body: some View {
VStack {
if let user = viewModel.user { //only display data if the user isn't nil
Text(user.username)
Text(user.firstName)
Text(user.lastName)
Text(user.email)
Text(user.uidFromFirebase)
}
}
}
}

I'd say a more traditional way of handling this might be to store your user profile document Users/uid/ -- that way you can just user document(uid) to find it rather than the whereField query.

Why is the data from firebase Firestore not coming into my view | Swift UI

try this approach, using .onAppear{...}:

struct LeaderBoardView: View {

@StateObject var leaderBoardModel = LeaderBoardModel() // <-- here

var body: some View {
List(leaderBoardModel.users) { item in
Text(item.name)
}.onAppear {
leaderBoardModel.getData() // <-- here
}
}
}

The view is not updated with data from Firestore in SwiftUI

The actions inside getData() are asynchronous. That means that what happens inside that function will not necessarily have executed by the time you call filteredProductByType() in your init method. So, on first run, it pretty much guarantees that filteredProducts will be empty.

To fix this, you could, for example, call filteredProductByType after your self.products = documents.map { closure inside getData.

That being said, a more efficient way of dealing with the problems would likely be to turn filteredProducts into a computed property that generates its results when called. Something like:

var filteredProducts: [Product] {
products.filter { $0.type == self.productType }
}

Then, you'd never have to call filteredProductByType and worry about the order that it happens.

SwiftUI: How to retrieve data from Firestore in second view?

In your DetailView, you're creating a new instance of FoodViewModel:

@ObservedObject var foodDatas = FoodViewModel()

That new instance has not fetched any data, and thus the index of the selection is out of bounds, because its array is empty.

You could pass your original ContentView's copy of the FoodDataModel as a parameter.

So, the previous line I quoted would become:

@ObservedObject var foodDatas : FoodViewModel

And then your NavigationLink would look like this:

NavigationLink(destination: DetailView(foodDatas: foodDatas, selection: self.$selection) //... etc

SwiftUI and MVVM: How to display data from Firebase/Firestore in View?

This is all about asynchronous retrieving, so you need to return results in callback, like

class FirebaseManager {
private let db = Firestore.firestore()

func getUploadedDecks(completion: @escaping ([FlashcardDeck]) -> ()) {

db.collection(K.FSCollectionName).getDocuments { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
fatalError("error downloading documents")
}

var uploadedDecks = [FlashcardDeck]()
for document in documents{
if let deck = try? document.data(as: FlashcardDeck.self) {
uploadedDecks.append(deck)
}
}
completion(uploadedDecks) // << here !!
}
// no return !!
}

and use it as

class DownloadViewModel: ObservableObject {

@Published var decks = [FlashcardDeck]()
@Published var show = false

func fetchDecks(){
FirebaseManager().getUploadedDecks() { [weak self] decks in
DispatchQueue.main.async {
// always update UI-linked properties on main queue
self?.decks = decks
}
}
}
}


Related Topics



Leave a reply



Submit