Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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()
}
question from:https://stackoverflow.com/questions/65651586/foreach-loop-in-swiftui-only-shows-first-in-array

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
336 views
Welcome To Ask or Share your Answers For Others

1 Answer

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)
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...