1

I am trying to show an array fetched from firebase with a ForEach in SwiftUI.

However, it is only showing the title of the first index of the array.

It seems like it does register how many items there are in the array, as it shows the correct number of views according to the number of items in the array but each item only has the title of the first item.

How do I make it show the title of all of the items in the array?

I fetch the project like so:

class ProjectRepository: ObservableObject
{
    private var cancellables: Set<AnyCancellable> = []
    
    private let store = Firestore.firestore()
    
    @Published var projects: [Project] = []
    
    init()
    {
        get()
    }
    
    // Retrieve projects from firebase
    func get()
    {
        store.collection(FirestoreKeys.CollectionPath.projects)
            .addSnapshotListener { querySnapshot, error in
                
                if let error = error {
                    print("Error getting projects: \(error.localizedDescription)")
                    return
                }
                
                self.projects = querySnapshot?.documents.compactMap{ document in
                    try? document.data(as: Project.self)
                } ?? []
            }
    }
    
    // Add projects to firebase
    func add(_ project: Project)
    {
        do {
            _ = try store.collection(FirestoreKeys.CollectionPath.projects).addDocument(from: project)
        } catch {
            fatalError("Unable to add card: \(error.localizedDescription)")
        }
    }
}

This is my project model:

struct Project: Identifiable, Codable
{
    @DocumentID var id: String?
    var title: String
    var image: String
    @ServerTimestamp var startDate: Date?
    @ServerTimestamp var endDate: Date?
    var tasks: [Task]
}

And this is my task model:

struct Task: Identifiable, Codable
{
    @DocumentID var id: String?
    var title: String
    var done: Bool
}

Finally this is how I am trying to show the tasks:

ScrollView {
    ForEach(projectViewModel.project.tasks) { task in
          HStack {
              Image(task.done ? "checkmark-filled" : "checkmark-unfilled")
              RoundedRectangle(cornerRadius: 20)
                 .foregroundColor(.white)
                 .frame(height: 72)
                 .shadow(color: Color.black.opacity(0.1), radius: 10, x: 0, y: 4)
                 .overlay(Text(task.title))
                 .padding(.leading)
          }
    }
    .padding()
}

1 Answer 1

2

I figured it out. It was because the task needed a unique ID and it didn't have a document ID.

I replaced the

@DocumentID var id: String?

with

var id: String? = UUID().uuidString

And added an id field to the tasks in Firestore.

I then showed the tasks in the list by calling

ForEach(projectViewModel.project.tasks, id: \.id) { task in
 (Insert code here)
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.