1. Übersicht
Willkommen zum Codelab FriendlyChat für iOS. In diesem Codelab erfahren Sie, wie Sie mit Firebase und modernen Swift-Funktionen wie SwiftUI, Swift Concurrency und dem Observation-Framework eine voll funktionsfähige iOS-App für Echtzeit-Chats erstellen.
Lerninhalte
- Status mit dem modernen Observation-Framework (
@Observable) verwalten. - Nutzer mit Firebase Authentication authentifizieren.
- Chatnachrichten in Echtzeit mit Cloud Firestore synchronisieren.
- Bilder mit Cloud Storage for Firebase speichern und bereitstellen.
- Mit modernen Swift Concurrency -Funktionen auf Firebase APIs zugreifen.
Voraussetzungen
- Die aktuelle Version von Xcode
- Ein iOS-Simulator oder ein physisches Testgerät
- Ein Google-Konto zum Erstellen und Verwalten Ihres Firebase-Projekts
2. Beispielcode abrufen
Klonen Sie das GitHub-Repository über die Befehlszeile:
$ git clone https://github.com/firebase/codelab-friendlychat-ios
Das Repository codelab-friendlychat-ios enthält mehrere Beispielprojekte:
ios-starter/swift-starter: Das Xcode-Startprojekt mit dem SwiftUI-Layoutgerüst undTODO-Kommentaren, in denen Sie App-Funktionen mit Firebase implementieren.ios/swift: Das abgeschlossene Xcode-Projekt mit der fertigen Beispiel-App.
3. Start-App erstellen
Erstellen und führen Sie die Start-App aus, um sich mit der Benutzeroberfläche vertraut zu machen:
- Wechseln Sie im Finder oder Terminal zum Verzeichnis
ios-starter/swift-starter. - Doppelklicken Sie auf
FriendlyChatSwift.xcodeproj, um das Projekt in Xcode zu öffnen. - Xcode löst Swift Package Manager-Abhängigkeiten automatisch im Hintergrund auf (Herunterladen von
firebase-ios-sdkVersion 12 oder höher von GitHub). - Wählen Sie einen iOS-Simulator aus (z. B. iPhone 17 Pro) und klicken Sie auf die Schaltfläche Ausführen (cmd + R).
Nach einigen Sekunden wird der Anmeldebildschirm von FriendlyChat angezeigt. An dieser Stelle sind die Anmeldeschaltflächen und Nachrichtenfeeds Platzhalter. In den folgenden Schritten verbinden Sie Firebase mit der App.
4. Firebase-Projekt einrichten
Neues Firebase-Projekt erstellen
- Melden Sie sich in der Firebase Console mit Ihrem Google-Konto an.
- Klicken Sie auf die Schaltfläche, um ein neues Projekt zu erstellen, und geben Sie dann einen Projektnamen ein (z. B.
FriendlyChat).
- Klicken Sie auf Weiter.
- Überprüfen und akzeptieren Sie gegebenenfalls die Firebase-Nutzungsbedingungen und klicken Sie dann auf Weiter.
- (Optional) Aktivieren Sie die KI-Unterstützung in der Firebase Console (Gemini in Firebase genannt).
- Für dieses Codelab benötigen Sie kein Google Analytics. Deaktivieren Sie daher die Google Analytics-Option.
- Klicken Sie auf Projekt erstellen, warten Sie, bis Ihr Projekt bereitgestellt wurde, und klicken Sie dann auf Weiter.
Firebase-Preismodell aktualisieren
Wenn Sie Cloud Storage for Firebase verwenden möchten, muss Ihr Firebase-Projekt auf den Blaze-Tarif (Pay as you go) umgestellt sein. Das bedeutet, dass es mit einem Cloud-Rechnungskonto verknüpft ist.
- Für ein Cloud-Rechnungskonto ist eine Zahlungsmethode wie eine Kreditkarte erforderlich.
- Wenn Sie Firebase und Google Cloud noch nicht kennen, prüfen Sie, ob Sie Anspruch auf ein Guthaben in Höhe von 300 $ und ein kostenloses Cloud-Rechnungskonto für den Testzeitraum haben.
- Wenn Sie dieses Codelab im Rahmen einer Veranstaltung durchführen, fragen Sie den Organisator, ob Cloud-Guthaben verfügbar sind.
So aktualisieren Sie Ihr Projekt auf den Blaze-Tarif:
- Wählen Sie in der Firebase Console aus, um Ihren Tarif zu aktualisieren.
- Wählen Sie den Blaze-Tarif aus. Folgen Sie der Anleitung auf dem Bildschirm, um ein Cloud-Rechnungskonto mit Ihrem Projekt zu verknüpfen.
Wenn Sie im Rahmen dieses Upgrades ein Cloud-Rechnungskonto erstellen mussten, müssen Sie möglicherweise zum Upgrade-Ablauf in der Firebase Console zurückkehren, um das Upgrade abzuschließen.
iOS-App verbinden
- Klicken Sie auf dem Bildschirm „Projektübersicht“ auf das Symbol iOS, um den Workflow für die App-Einrichtung zu starten.
- Geben Sie die Paket-ID ein:
com.google.firebase.codelab.FriendlyChatSwift - Klicken Sie auf App registrieren.
GoogleService-Info.plist zum Xcode-Projekt hinzufügen
- Klicken Sie auf GoogleService-Info.plist herunterladen , um die Konfigurationsdatei zu speichern.
- Ziehen Sie in Xcode die heruntergeladene Datei
GoogleService-Info.plistin der Projektnavigation in die HauptgruppeFriendlyChatSwift. - Prüfen Sie, ob Elemente bei Bedarf kopieren ausgewählt ist und das Ziel
FriendlyChatSwiftausgewählt ist, und klicken Sie dann auf Fertig.
Firebase in FriendlyChatSwiftApp.swift konfigurieren
Initialisieren Sie Firebase schließlich mit Ihrer Projektkonfiguration, wenn Ihre SwiftUI-App gestartet wird. Öffnen Sie FriendlyChatSwiftApp.swift und ersetzen Sie die TODO-Platzhalter durch import FirebaseCore und FirebaseApp.configure():
import SwiftUI
import FirebaseCore
@main
struct FriendlyChatSwiftApp: App {
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
5. Nutzer authentifizieren
Authentifizierung in der Firebase Console konfigurieren
Bevor Sie Nutzer authentifizieren können, müssen Sie zuerst den gewünschten Authentifizierungsanbieter in der Firebase Console aktivieren. In dieser Anleitung wird die Authentifizierung per E‑Mail/Passwort verwendet:
- Wechseln Sie in der Firebase Console zu Sicherheit > Authentifizierung und klicken Sie dann auf Jetzt starten.
- Wählen Sie den Tab Anmeldemethode aus.
- Klicken Sie auf E‑Mail/Passwort, aktivieren Sie den Schalter Aktivieren und klicken Sie auf Speichern.
Cloud Firestore mit Authentifizierungsregeln schützen
Als Nächstes müssen sich Nutzer authentifizieren, bevor sie Nachrichten lesen oder schreiben können:
- Wechseln Sie in der Firebase Console zu Datenbanken und Speicher > Firestore-Datenbank und klicken Sie dann auf Datenbank erstellen.
- Wählen Sie einen Standort aus und klicken Sie auf Weiter.
- Wählen Sie Im Testmodus starten aus und klicken Sie auf Erstellen.
- Wählen Sie den Tab Regeln aus und aktualisieren Sie die Sicherheitsregeln auf:
Mit diesen Regeln kann jeder authentifizierte Nutzer Nachrichten in der Datenbank lesen oder schreiben. Das ist für Lernzwecke geeignet. Weitere Informationen zu Sicherheitsregeln finden Sie in der Dokumentation zu Sicherheitsregeln.rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /messages/{messageId} { allow read, write: if request.auth != null; } } } - Klicken Sie auf Veröffentlichen.
Authentifizierungsstatus in UserViewModel.swift beobachten
In SwiftUI sorgt die reaktive Beobachtung des Firebase Auth-Status dafür, dass die Benutzeroberfläche reibungslos zwischen dem Anmeldebildschirm und der Chat-Oberfläche wechselt.
Öffnen Sie ViewModels/UserViewModel.swift und ersetzen Sie das TODO in init(), um Änderungen am Authentifizierungsstatus mit der AsyncSequence authStateChanges zu beobachten:
init() {
authTask = Task {
for await user in Auth.auth().authStateChanges {
self.user = user
}
}
}
Anmeldung, Registrierung und Abmeldung mit Swift Concurrency implementieren
Ersetzen Sie in UserViewModel.swift die verbleibenden TODO-Kommentare durch moderne async/await-Authentifizierungsmethoden:
func signIn(email: String, password: String) async {
errorMessage = nil
if email.isEmpty || password.isEmpty {
showError("Please enter both email and password.")
return
}
do {
try await Auth.auth().signIn(withEmail: email, password: password)
} catch {
showError(error.localizedDescription)
}
}
func signUp(email: String, password: String, displayName: String) async {
errorMessage = nil
if email.isEmpty || password.isEmpty {
showError("Please enter both email and password.")
return
}
do {
let result =
try await Auth.auth().createUser(withEmail: email, password: password)
let changeRequest = result.user.createProfileChangeRequest()
changeRequest.displayName = displayName.isEmpty ? email : displayName
try await changeRequest.commitChanges()
self.user = Auth.auth().currentUser
} catch {
showError(error.localizedDescription)
}
}
func updateDisplayName(_ displayName: String) async {
guard let currentUser = Auth.auth().currentUser else { return }
do {
let changeRequest = currentUser.createProfileChangeRequest()
changeRequest.displayName = displayName
try await changeRequest.commitChanges()
self.user = Auth.auth().currentUser
} catch {
showError(error.localizedDescription)
}
}
func signOut() {
do {
try Auth.auth().signOut()
} catch {
showError(error.localizedDescription)
}
}
Nutzerauthentifizierung testen
- Klicken Sie in Xcode auf die Schaltfläche Ausführen.
- Klicken Sie im App-Simulator auf Registrieren, geben Sie einen Anzeigenamen, eine E‑Mail-Adresse und ein Passwort ein und tippen Sie auf REGISTRIEREN.
- Sie sollten automatisch authentifiziert und zum leeren Nachrichtenbildschirm weitergeleitet werden.
6. Aus Cloud Firestore lesen
Beispielnachrichten in der Firebase Console hinzufügen
Füllen Sie die Datenbank mit Beispielnachrichten:
- Wechseln Sie in der Firebase Console zu Firestore-Datenbank und wählen Sie den Tab Daten aus.
- Klicken Sie auf Sammlung starten.
- Geben Sie
messagesfür die Sammlungs-ID ein und klicken Sie dann auf Weiter. - Lassen Sie die Dokument-ID auf „Automatisch generieren“ eingestellt (oder klicken Sie auf Auto-ID).
- Fügen Sie dem Dokument die folgenden Felder hinzu:
text(Typ:string, Wert:Hello)displayName(Typ:string, Wert:anonymous)
- Klicken Sie auf Speichern.
- Optional können Sie auf Dokument hinzufügen klicken, um weitere Beispielnachrichten hinzuzufügen.
Nachrichten in FriendlyMessageViewModel.swift synchronisieren
In SwiftUI steuert ein @Observable-Modell deklarative UI-Updates. Öffnen Sie ViewModels/FriendlyMessageViewModel.swift und implementieren Sie startListening() und stopListening() mit der AsyncSequence snapshots:
func startListening() {
stopListening()
listenerTask = Task {
let db = Firestore.firestore()
do {
for try await snapshot in db.collection("messages").snapshots {
self.messages = snapshot.documents.compactMap { document in
try? document.data(as: FriendlyMessage.self)
}
}
} catch {
print("Error listening for messages: \(error)")
}
}
}
func stopListening() {
listenerTask?.cancel()
listenerTask = nil
messages.removeAll()
}
So rendert und scrollt SwiftUI Nachrichten automatisch
In Views/ContentView.swift sehen Sie, wie ScrollViewReader und LazyVStack Chatblasen rendern und automatisch zur neuesten Nachricht scrollen, wenn sich messages.count ändert:
ScrollViewReader { scrollViewReader in
ScrollView {
LazyVStack(spacing: 12) {
ForEach(messageViewModel.messages) { message in
FriendlyMessageView(friendlyMessage: message)
.id(message.id)
}
}
.padding(.horizontal)
.onChange(of: messageViewModel.messages.count) { _, count in
guard count > 0,
let lastId = messageViewModel.messages.last?.id else { return }
withAnimation(.easeInOut) {
scrollViewReader.scrollTo(lastId, anchor: .bottom)
}
}
}
}
Indem der Datenbankstatus über das Ansichtsmodell direkt mit dem UI-Status verknüpft wird, kann der App-Code Übergänge sauber Animationen zuordnen. Im nächsten Schritt schreiben Sie Daten aus der App in die Datenbank, um diese Animation in Aktion zu sehen.
7. Nachrichten senden
sendMessage mit Swift Concurrency implementieren
Wenn Sie mit addDocument() ein Dokument zu einer Sammlung hinzufügen, generiert Cloud Firestore eine eindeutige ID für jede Chatnachricht.
Ersetzen Sie in ViewModels/FriendlyMessageViewModel.swift das TODO in sendMessage(text:imageUrl:) durch eine async throws-Methode:
func sendMessage(text: String?, imageUrl: String?) async throws {
guard let currentUser = Auth.auth().currentUser else { return }
let message = FriendlyMessage(
text: text,
displayName: currentUser.displayName ?? currentUser.email ?? "Anonymous",
imageUrl: imageUrl,
userId: currentUser.uid
)
let db = Firestore.firestore()
_ = try db.collection("messages").addDocument(from: message)
}
Das Senden von Nachrichten testen
- Klicken Sie in Xcode auf die Schaltfläche Ausführen.
- Melden Sie sich in Ihrem Konto an.
- Geben Sie eine Nachricht in das Textfeld unten ein und tippen Sie auf das Symbol „Senden“.
- Die Nachricht wird sofort im Simulator angezeigt.
8. Bilder speichern und empfangen
Cloud Storage for Firebase einrichten
- Wechseln Sie in der Firebase Console zu Datenbanken und Speicher > Speicher und klicken Sie dann auf Jetzt starten.
- Wählen Sie Im Testmodus starten aus und klicken Sie auf Weiter.
- Übernehmen Sie den Standardspeicherort und klicken Sie auf Fertig.
Native Bildauswahl mit SwiftUI PhotosPicker
Modernes SwiftUI (iOS 16 oder höher) bietet eine native Fotoauswahl über PhotosPicker aus import PhotosUI. Es sind keine UIKit-Delegatbrücken oder UIImagePickerController-Wrapper erforderlich.
In Views/FooterView.swift sehen Sie, wie PhotosPicker ausgewählte Bilder bindet:
PhotosPicker(selection: $selectedItem, matching: .images) {
Image(systemName: "photo.on.rectangle.angled")
.font(.system(size: 26))
.foregroundStyle(.blue)
.accessibilityLabel("Select photo")
}
.onChange(of: selectedItem) { _, newItem in
Task {
if let data = try? await newItem?.loadTransferable(type: Data.self) {
await uploadAndSendImage(data: data)
}
}
}
Bild-Upload implementieren
Wenn ein Foto ausgewählt ist, laden Sie die Bilddaten in Cloud Storage hoch und speichern Sie die öffentliche Download-URL in Cloud Firestore.
Ersetzen Sie in Views/FooterView.swift das TODO in uploadAndSendImage(data:):
private func uploadAndSendImage(data: Data) async {
guard let uid = Auth.auth().currentUser?.uid else { return }
isUploading = true
defer {
isUploading = false
selectedItem = nil
}
do {
let filename = "\(uid)/\(UUID().uuidString).jpg"
let storageRef =
Storage.storage().reference().child("images").child(filename)
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
_ = try await storageRef.putDataAsync(data, metadata: metadata)
let downloadURL = try await storageRef.downloadURL()
try await viewModel.sendMessage(
text: nil, imageUrl: downloadURL.absoluteString)
} catch {
print("Error uploading image: \(error.localizedDescription)")
}
}
Bilder mit Cloud Storage freigeben
In Views/FriendlyMessageImageView.swift werden Bild-URLs asynchron mit Swift Concurrency und dem Cloud Storage SDK geladen:
- Standardmäßige HTTP/HTTPS-Download-URLs werden asynchron über
URLSessionabgerufen. - Google Cloud Storage-URLs (z. B.
gs://...) werden mitStorage.storage().reference(forURL:)abgerufen.
Bildnachrichten testen
- Klicken Sie in Xcode auf die Schaltfläche Ausführen.
- Melden Sie sich in Ihrem Konto an.
- Tippen Sie auf das Fotosymbol, wählen Sie ein Bild aus der Mediathek aus und sehen Sie zu, wie es hochgeladen wird und im Chat erscheint.
9. Fazit
Herzlichen Glückwunsch! Sie haben mit Swift und Firebase erfolgreich eine iOS-App für Echtzeit-Chats erstellt.
Das haben Sie gelernt
- Swift Package Manager (SPM) -Xcode-Integration für
firebase-ios-sdk. - SwiftUI -Deklarative Layouts,
PhotosPickerund automatisches Scrollen mitScrollViewReader. - Swift Concurrency (
async/await) für Authentifizierung, Cloud Firestore und Cloud Storage. - Authentifizierung per E‑Mail/Passwort und anonyme Authentifizierung mit reaktiver Statusbeobachtung.
- Cloud Firestore -Echtzeit-Snapshot-Abhören und automatisierte ID-Schreibvorgänge.
- Cloud Storage for Firebase -Binäruploads und öffentliche Download-URLs.