I have tried my first SwiftUI Project. I only want to show some data stored in Firestore (Google Firebase). Here is my code:
import SwiftUI import FirebaseFirestore import FirebaseFirestoreSwift struct MonsterObj: Identifiable, Equatable, Hashable { var id = UUID() var name: String var element: String var immune: String var size: String var twoStarWeakness: String var threeStarWeakness: String #if DEBUG static let exampleMonster = MonsterObj(id: UUID(), name: "Test Monster", element: "Test Element", immun: "Test immun", groesse: "Test groesse", twoStarWeakness: "Test 2 Weakness", threeStarWeakness: "Test3 Weakness") #endif } class MonsterC: ObservableObject { @Published var monsters = [MonsterObj]() init() { let db = Firestore.firestore() var monsterNames: [String] = [] db.collection("Monster").getDocuments() { (querySnapshot, err) in if let err = err { print(err) } else { for document in querySnapshot!.documents { monsterNames.append("\(document.documentID)") print("document: \(document.documentID)") } } } for monsterName in monsterNames { print(monsterName) db.collection("Monster").document(monsterName).getDocument { (document, error) in if let document = document, document.exists { let elementGetter = document.get("element") as! String let immuneGetter = document.get("immune") as! String let sizeGetter = document.get("size") as! String let twoStarWeaknessGetter = document.get("2 star weakness") as! String let threeStarWeaknessGetter = document.get("3 star weakness")as! String self.monsters.append(MonsterObj(name: monsterName, element: elementGetter, immune: immuneGetter, size: sizeGetter, twoStarWeakness: twoStarWeaknessGetter, threeStarWeakness: threeStarWeaknessGetter)) } } } } } This is my View:
import SwiftUI struct ContentView: View { @EnvironmentObject var monsterT: MonsterC var body: some View { List(monsterT.monsters, id: \.self) { monster in Text(monster.name) } } } And I did following to SceneDelegate.swift:
var window: UIWindow? var monsterT = MonsterC() func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions { // Create the SwiftUI view that provides the window contents. let contentView = ContentView().environmentObject(monsterT) if let windowScene = scene as? UIWindowScene { let window = UIWindow(windowScene: windowScene) window.rootViewController = UIHostingController(rootView: contentView) self.window = window window.makeKeyAndVisible() } } So my Problem is the list is empty. I figured out in init of class MonsterC the line monsterNames.append("\document.documentID)") does not append anything to monsterNames. But print("document: \(document.documentID)") is printing all monsterNames.
My google Firestore structure looks like this:
Collection -> Document -> Fields ------------------------------------------- Monster -> Anjanath -> immune: fire, element: fire etc. There's only one collection ("Monster").
Can anyone explain to a beginner why .append is not working here but print is doing everything right?
print("After monstersNames.append: \monsterNames)")Could it be because you are missing the asychrone concept?