0
0
iOS Swiftmobile~20 mins

Cloud Firestore in iOS Swift - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Simple Firestore Notes
A screen to add, list, and delete notes stored in Cloud Firestore.
Target UI
-------------------------
| Simple Firestore Notes |
-------------------------
| + Add Note             |
|-----------------------|
| - Note 1              |
| - Note 2              |
| - Note 3              |
-------------------------
Display a list of notes fetched from Firestore collection 'notes'.
Add a '+' button in the navigation bar to add a new note.
When '+' is tapped, show an alert with a text field to enter note text.
Save the new note to Firestore and update the list.
Each note row has a delete swipe action to remove the note from Firestore.
Use Firestore's real-time listener to update the list automatically.
Starter Code
iOS Swift
import SwiftUI
import Firebase

struct NotesView: View {
    @State private var notes: [Note] = []

    var body: some View {
        NavigationView {
            List {
                // TODO: Show notes here
            }
            .navigationTitle("Simple Firestore Notes")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: {
                        // TODO: Show add note alert
                    }) {
                        Image(systemName: "plus")
                    }
                }
            }
            // TODO: Add Firestore listener
        }
    }
}

struct Note: Identifiable {
    var id: String
    var text: String
}

// TODO: Add Firestore functions here

struct NotesView_Previews: PreviewProvider {
    static var previews: some View {
        NotesView()
    }
}
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
iOS Swift
import SwiftUI
import Firebase

struct NotesView: View {
    @State private var notes: [Note] = []
    @State private var showingAddNote = false
    @State private var newNoteText = ""

    private var db = Firestore.firestore()

    var body: some View {
        NavigationView {
            List {
                ForEach(notes) { note in
                    Text(note.text)
                }
                .onDelete(perform: deleteNote)
            }
            .navigationTitle("Simple Firestore Notes")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: {
                        showingAddNote = true
                    }) {
                        Image(systemName: "plus")
                    }
                    .accessibilityLabel("Add note")
                }
            }
            .onAppear(perform: listenToNotes)
            .alert("Add New Note", isPresented: $showingAddNote, actions: {
                TextField("Note text", text: $newNoteText)
                Button("Save", action: addNote)
                Button("Cancel", role: .cancel, action: {
                    newNoteText = ""
                })
            })
        }
    }

    func listenToNotes() {
        db.collection("notes").addSnapshotListener { snapshot, error in
            guard let documents = snapshot?.documents else {
                print("No documents")
                return
            }
            notes = documents.map { doc in
                let data = doc.data()
                let text = data["text"] as? String ?? ""
                return Note(id: doc.documentID, text: text)
            }
        }
    }

    func addNote() {
        let trimmed = newNoteText.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty else { return }
        db.collection("notes").addDocument(data: ["text": trimmed])
        newNoteText = ""
        showingAddNote = false
    }

    func deleteNote(at offsets: IndexSet) {
        offsets.forEach { index in
            let note = notes[index]
            db.collection("notes").document(note.id).delete()
        }
    }
}

struct Note: Identifiable {
    var id: String
    var text: String
}

struct NotesView_Previews: PreviewProvider {
    static var previews: some View {
        NotesView()
    }
}

This solution uses SwiftUI with Firebase Firestore to create a simple notes app.

We use addSnapshotListener to listen for real-time updates from the 'notes' collection. This keeps the list updated automatically.

The '+' button shows an alert with a text field to enter a new note. When saved, it adds a document to Firestore.

Notes are displayed in a list with swipe-to-delete enabled. Deleting removes the document from Firestore.

Accessibility label is added to the add button for screen readers.

Final Result
Completed Screen
-------------------------
| Simple Firestore Notes |
-------------------------
| + Add Note             |
|-----------------------|
| - Buy groceries        |
| - Call mom             |
| - Walk the dog         |
-------------------------
Tap '+' button to open alert with text field.
Enter note text and tap 'Save' to add note to Firestore and update list.
Swipe left on a note to reveal 'Delete' and remove it from Firestore.
List updates automatically when notes change in Firestore.
Stretch Goal
Add pull-to-refresh to manually refresh notes list.
💡 Hint
Use SwiftUI's .refreshable modifier on the List and call a Firestore fetch function.