ContentView.swift
// // ContentView.swift // DevSwiftUI // // Created by Cairocoders // import SwiftUI import Firebase import FirebaseFirestoreSwift struct ContentView: View { private var db: Firestore @State private var storeName: String = "" @State private var stores: [Store] = [] init() { db = Firestore.firestore() } private func saveStore(store: Store) { _ = try? db.collection("stores") .addDocument(from: store) { error in if let error = error { print(error.localizedDescription) } else { print("Document has been saved!") getAllStores() } } } private func getAllStores() { db.collection("stores") .getDocuments { (snapshot, error) in if let error = error { print(error.localizedDescription) } else { if let snapshot = snapshot { stores = snapshot.documents.compactMap { doc in var store = try? doc.data(as: Store.self) if store != nil { store!.id = doc.documentID } return store } } } } } private func deleteStore(at indexSet: IndexSet) { indexSet.forEach { index in let store = stores[index] // delete from the firestore database db.collection("stores") .document(store.id!) .delete { error in if let error = error { print(error.localizedDescription) } else { getAllStores() } } } } var body: some View { NavigationView { VStack { TextField("Enter store name", text: $storeName) .font(.title2) .modifier(customViewModifier(roundedCornes: 6, startColor: .orange, endColor: .purple, textColor: .white)) Button("Save Store") { saveStore(store: Store(name: storeName)) } .frame(width: 200) .padding() .foregroundColor(.white) .background(Color.orange) .cornerRadius(40) List { ForEach(stores, id: \.name) { store in NavigationLink( destination: StoreDetailsView(store: store)) { Text(store.name) } }.onDelete(perform: deleteStore) }.listStyle(PlainListStyle()) Spacer() .onAppear(perform: { getAllStores() }) }.padding() .navigationTitle("Grocery") } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct customViewModifier: ViewModifier { var roundedCornes: CGFloat var startColor: Color var endColor: Color var textColor: Color func body(content: Content) -> some View { content .padding() .background(LinearGradient(gradient: Gradient(colors: [startColor, endColor]), startPoint: .topLeading, endPoint: .bottomTrailing)) .cornerRadius(roundedCornes) .padding(3) .foregroundColor(textColor) .overlay(RoundedRectangle(cornerRadius: roundedCornes) .stroke(LinearGradient(gradient: Gradient(colors: [startColor, endColor]), startPoint: .topLeading, endPoint: .bottomTrailing), lineWidth: 2.5)) .font(.custom("Open Sans", size: 18)) .shadow(radius: 10) } }StoreDetailsView.swift
// // StoreDetailsView.swift // DevSwiftUI // // Created by Cairocoders // import SwiftUI import Firebase import FirebaseFirestoreSwift struct StoreDetailsView: View { @State var store: Store @State private var storeName: String = "" @State private var groceryItemName: String = "" let db = Firestore.firestore() private func updateStore() { db.collection("stores") .document(store.id!) .updateData(["name": storeName]) { error in if let error = error { print(error.localizedDescription) } else { print("Store has been updated!") } } } private func loadGroceryItems() { let ref = db.collection("stores") .document(store.id!) ref.getDocument { doc, error in if let doc = doc, doc.exists { if let store = try? doc.data(as: Store.self) { self.store = store self.store.id = doc.documentID } } else { print("Document does not exists!") } } } private func saveGroceryItem() { db.collection("stores") .document(store.id!) .updateData([ "items": FieldValue.arrayUnion([groceryItemName]) ]) { error in if let error = error { print(error.localizedDescription) } else { // load the docs and populate the items loadGroceryItems() } } } var body: some View { NavigationView { VStack { TextField("Enter item name", text: $groceryItemName) .font(.title2) .modifier(customViewModifier(roundedCornes: 6, startColor: .orange, endColor: .purple, textColor: .white)) Button("Add Item") { saveGroceryItem() } .frame(width: 200) .padding() .foregroundColor(.white) .background(Color.orange) .cornerRadius(40) if let items = store.items { List(items, id: \.self) { item in Text(item) }.listStyle(GroupedListStyle()) } Spacer() }.padding() }.navigationTitle(store.name) } } struct StoreDetailsView_Previews: PreviewProvider { static var previews: some View { StoreDetailsView(store: Store(id: "333", name: "HEB")) } }Store.swift
// // Store.swift // DevSwiftUI // // Created by Cairocoders // import Foundation struct Store: Codable { var id: String? let name: String var items: [String]? = nil }DevSwiftUIApp.swift
// // DevSwiftUIApp.swift // DevSwiftUI // // Created by Cairocoders // import SwiftUI import Firebase @main struct DevSwiftUIApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { ContentView() } } } class AppDelegate: NSObject,UIApplicationDelegate{ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { FirebaseApp.configure() return true } }