Home > OS >  Display data from firestore
Display data from firestore

Time:05-03

I am trying to display the data I get back from the firestore in my swiftUI app but am having some trouble.

Here is where I get the data

import Foundation
import Firebase

class RecipesViewModel: ObservableObject {
    
    @Published var userRecipes = [RecipesData]()
    
    func getData() {
        
        // Get a reference to the database
        let db = Firestore.firestore()
        
        // Read the documents at a specific path
        db.collection("Recipes").getDocuments { snapshot, error in
            
            // Check for errors
            if error == nil {
                // No errors
                
                if let snapshot = snapshot {
                    
                    // Update the list property in the main thread
                    DispatchQueue.main.async {
                        
                        
                        self.userRecipes = snapshot.documents.map { d in
                            
                            return RecipesData(id: d["id"] as? String ?? "", name: d["name"] as? String ?? "", cuisine: d["cuisine"] as? String ?? "", difficulty: d["difficulty"] as? String ?? "", dishType: d["dishType"] as? String ?? "", prepMins: d["prepMins"] as? Int ?? 0, prepHours: d["prephours"] as? Int ?? 0, cookMins: d["cookMins"] as? Int ?? 0, cookHours: d["cookHours"] as? Int ?? 0, restMins: d["restMins"] as? Int ?? 0, restHours: d["restHours"] as? Int ?? 0, likes: d["lkies"] as? Int ?? 0)
                        }
                    }
                    
                    
                }
            }
            else {
                
            }
        }
    }
    
}

and here is where the data gets stored

import SwiftUI
import FirebaseFirestoreSwift

struct RecipesData: Identifiable{
    var id: String
    var name: String
    var cuisine: String
    var difficulty: String
    var dishType: String
    var prepMins: Int
    var prepHours: Int
    var cookMins: Int
    var cookHours: Int
    var restMins: Int
    var restHours: Int
    var likes: Int
}

I can get the Data and if I choose to display the name of each recipe in a list I can do that.

But what I want to do is to have my data too like this when being displayed

import SwiftUI

struct AllRecipesView: View {
    
    @ObservedObject var model = RecipesViewModel()
    private var gridCollum = [GridItem(.flexible(),spacing: 0), GridItem(.flexible(),spacing: 0)]
    
    var body: some View {
        VStack{
            LazyVGrid(columns: gridCollum, spacing: 0){
                ForEach(model.userRecipes) {item in
                    overlayView()
                }
            }
        }
    }
    init(){
        model.getData()
    }
}

struct AllRecipesView_Previews: PreviewProvider {
    static var previews: some View {
        AllRecipesView()
    }
}


struct overlayView:View{
    
    @ObservedObject var model = RecipesViewModel()
    
    var body: some View{
        ForEach(model.userRecipes) {item in
            VStack{
                VStack{
                    Spacer()
                    HStack{
                        HStack{
                            Image(systemName: "star")
                                .foregroundColor(.white)
                                .font(.system(size: 20))
                            Text(item.likes)
                                .foregroundColor(.white)
                                .font(.system(size: 15))
                            
                        }
                        .padding(.trailing)
                        Text(item.prepMins)
                            .foregroundColor(.white)
                            .font(.system(size: 15))
                            .padding(.horizontal)
                        
                    }
                    .padding(.bottom)
                }
                .frame(width:180,height:130)
                .background(Color.red)
                .cornerRadius(8)
                .shadow(color: .black, radius: 3, x: 2, y: 2)
                .padding(.bottom)
                Text("Salmon and Rice")
                Text("Some User")
            }
            
        }
    }
    init(){
        model.getData()
    }
}

But I keep getting error saying No exact matches in call to initializer on the lines

Text(item.likes)

and

Text(prepMins)

How can I fix my errors please

CodePudding user response:

try something like this example code, using @StateObject var model = RecipesViewModel() and passing it using @EnvironmentObject. To fix the errors you get, remenber Text() needs a string, such as, Text(String(item.likes)) or Text("\(item.likes)").

struct AllRecipesView: View {
    
    @StateObject var model = RecipesViewModel() // <-- here
    
    private var gridCollum = [GridItem(.flexible(),spacing: 0), GridItem(.flexible(),spacing: 0)]
    
    var body: some View {
        VStack{
            LazyVGrid(columns: gridCollum, spacing: 0){
                ForEach(model.userRecipes) {item in
                    OverlayView()
                }
            }
        }
        .environmentObject(model)  // <-- here
        .onAppear {
            model.getData()  // <-- here
        }
    }
}

struct OverlayView:View{
    
    @EnvironmentObject var model: RecipesViewModel // <-- here
    
    var body: some View{
        ForEach(model.userRecipes) {item in
            VStack{
                VStack{
                    Spacer()
                    HStack{
                        HStack{
                            Image(systemName: "star")
                                .foregroundColor(.white)
                                .font(.system(size: 20))
                            Text(String(item.likes)) // <-- here
                                .foregroundColor(.white)
                                .font(.system(size: 15))
                            
                        }
                        .padding(.trailing)
                        Text(String(item.prepMins))  // <-- here
                            .foregroundColor(.white)
                            .font(.system(size: 15))
                            .padding(.horizontal)
                        
                    }
                    .padding(.bottom)
                }
                .frame(width:180,height:130)
                .background(Color.red)
                .cornerRadius(8)
                .shadow(color: .black, radius: 3, x: 2, y: 2)
                .padding(.bottom)
                Text("Salmon and Rice")
                Text("Some User")
            }
        }
    }
}
  • Related