1. Übersicht
In diesem Codelab erfahren Sie, wie Sie Firebase Data Connect in eine Cloud SQL-Datenbank einbinden, um mit SwiftUI eine Filmbewertungs-App für iOS zu erstellen.
Sie erfahren, wie Sie Ihre iOS-Anwendung mit Firebase Data Connect mit einer Cloud SQL-Datenbank verbinden, um eine nahtlose Datensynchronisierung für Filmbesprechungen zu ermöglichen.
Am Ende dieses Codelabs haben Sie eine funktionierende iOS-App, mit der Nutzer Filme durchsuchen und als Favoriten markieren können. Die App wird von einer Cloud SQL-Datenbank unterstützt, die auf Firebase Data Connect basiert.
Lerninhalte
In diesem Codelab lernen Sie Folgendes:
- Richten Sie Firebase Data Connect ein und verwenden Sie die Firebase Emulator Suite, um schnell Ergebnisse zu erhalten.
- Datenbankschema mit Data Connect und GraphQL entwerfen
- Erstellen Sie ein typsicheres Swift-SDK aus Ihrem Datenbankschema und fügen Sie es einer Swift-Anwendung hinzu.
- Implementieren Sie die Nutzerauthentifizierung und binden Sie sie in Firebase Data Connect ein, um die Daten Ihrer Nutzer zu schützen.
- Mit Abfragen und Mutationen, die auf GraphQL basieren, können Sie Daten in Cloud SQL abrufen, aktualisieren, löschen und verwalten.
- Optional: Stellen Sie einen Data Connect-Dienst für die Produktion bereit.
Vorbereitung
- Die aktuelle Version von Xcode
- Der Beispielcode für das Codelab. Sie laden den Beispielcode in einem der ersten Schritte des Codelabs herunter.
2. Beispielprojekt einrichten
Firebase-Projekt erstellen
- Melden Sie sich mit Ihrem Google-Konto in der Firebase Console an.
- Klicken Sie auf die Schaltfläche, um ein neues Projekt zu erstellen, und geben Sie dann einen Projektnamen ein (z. B.
Friendly Flix
).
- Klicken Sie auf Weiter.
- Lesen und akzeptieren Sie bei Aufforderung die Firebase-Nutzungsbedingungen und klicken Sie dann auf Weiter.
- (Optional) Aktivieren Sie die KI-Unterstützung in der Firebase Console (als „Gemini in Firebase“ bezeichnet).
- 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.
Code herunterladen
Führen Sie den folgenden Befehl aus, um den Beispielcode für dieses Codelab zu klonen. Dadurch wird auf Ihrem Computer ein Verzeichnis mit dem Namen codelab-dataconnect-ios
erstellt:
git clone https://github.com/FirebaseExtended/codelab-dataconnect-ios`
Wenn Sie Git nicht auf Ihrem Computer haben, können Sie den Code auch direkt von GitHub herunterladen.
Firebase-Konfiguration hinzufügen
Das Firebase SDK verwendet eine Konfigurationsdatei, um eine Verbindung zu Ihrem Firebase-Projekt herzustellen. Auf Apple-Plattformen heißt diese Datei GoogleServices-Info.plist
. In diesem Schritt laden Sie die Konfigurationsdatei herunter und fügen sie Ihrem Xcode-Projekt hinzu.
- Wählen Sie in der Firebase Console im linken Navigationsbereich Projektübersicht aus.
- Klicken Sie auf die Schaltfläche iOS+, um die Plattform auszuwählen. Geben Sie im Feld Apple-Bundle-ID den Wert
com.google.firebase.samples.FriendlyFlix
ein. - Klicken Sie auf App registrieren und folgen Sie der Anleitung, um die
GoogleServices-Info.plist
-Datei herunterzuladen. - Verschieben Sie die heruntergeladene Datei in das Verzeichnis
start/FriendlyFlix/app/FriendlyFlix/FriendlyFlix/
des gerade heruntergeladenen Codes und ersetzen Sie die vorhandene DateiGoogleServices-Info.plist
. - Klicken Sie dann einige Male auf Weiter, um das Einrichtungsprojekt in der Firebase Console abzuschließen. Sie müssen das SDK nicht der App hinzufügen, da dies bereits im Starterprojekt erfolgt ist.
- Klicken Sie abschließend auf Weiter zur Konsole, um die Einrichtung abzuschließen.
3. Data Connect einrichten
Installation
Automatische Installation
Führen Sie den folgenden Befehl im Verzeichnis codelab-dataconnect-ios/FriendlyFlix
aus:
curl -sL https://firebase.tools/dataconnect | bash
Dieses Skript versucht, die Entwicklungsumgebung für Sie einzurichten und eine browserbasierte IDE zu starten. Diese IDE bietet Tools, einschließlich einer vorab gebündelten VS Code-Erweiterung, mit denen Sie Ihr Schema verwalten, Abfragen und Mutationen für Ihre Anwendung definieren und stark typisierte SDKs generieren können.
Nachdem Sie das Skript ausgeführt haben, sollte VS Code automatisch geöffnet werden.
Nachdem Sie dies einmal getan haben, können Sie VS Code starten, indem Sie VS Code im lokalen Verzeichnis ausführen:
code .
Manuelle Installation
- Visual Studio Code installieren
- Installieren Sie Node.js.
- Öffnen Sie in VS Code das Verzeichnis
codelab-dataconnect-ios/FriendlyFlix
. - Installieren Sie die Firebase Data Connect-Erweiterung über den Visual Studio Code Marketplace.
Data Connect im Projekt initialisieren
Klicken Sie im linken Bereich auf das Firebase-Symbol, um die Benutzeroberfläche der Data Connect VS Code-Erweiterung zu öffnen.
- Klicken Sie auf die Schaltfläche Über Google anmelden. Ein Browserfenster wird geöffnet. Folgen Sie der Anleitung, um sich mit Ihrem Google-Konto in der Erweiterung anzumelden.
- Klicken Sie auf die Schaltfläche Firebase-Projekt verknüpfen und wählen Sie das Projekt aus, das Sie zuvor in der Console erstellt haben.
- Klicken Sie auf die Schaltfläche firebase init ausführen und folgen Sie der Anleitung im integrierten Terminal.
SDK-Generierung konfigurieren
Wenn Sie auf die Schaltfläche firebase init ausführen klicken, sollte die Firebase Data Connect-Erweiterung ein dataconnect
-Verzeichnis für Sie initialisieren.
Öffnen Sie in VS Code die Datei dataconnect/connector/connector.yaml
. Dort finden Sie die Standardkonfiguration.
Aktualisieren Sie die Konfiguration und verwenden Sie die folgenden Einstellungen, damit der generierte Code mit diesem Codelab funktioniert. Achten Sie insbesondere darauf, dass connectorId
auf friendly-flix
und das Swift-Paket auf FriendlyFlixSDK
gesetzt ist.
connectorId: "friendly-flix"
generate:
swiftSdk:
outputDir: "../../app"
package: "FriendlyFlixSDK"
observablePublisher: observableMacro
Das bedeuten die Einstellungen:
connectorId
: ein eindeutiger Name für diesen Connector.outputDir
: Pfad, in dem das generierte Data Connect SDK gespeichert wird. Dieser Pfad bezieht sich auf das Verzeichnis, das dieconnector.yaml
-Datei enthält.package
: Der Paketname, der für das generierte Swift-Paket verwendet werden soll.
Sobald Sie diese Datei speichern, generiert Firebase Data Connect ein Swift-Paket mit dem Namen FriendlyFlixSDK
und platziert es neben dem Projektordner FriendlyFlix
.
Firebase-Emulatoren starten
Wechseln Sie in VS Code zur Firebase-Ansicht und klicken Sie dann auf die Schaltfläche Emulatoren starten.
Dadurch wird der Firebase-Emulator im integrierten Terminal gestartet. Die Ausgabe sollte in etwa so aussehen:
npx -y firebase-tools@latest emulators:start --project <your-project-id>
Generiertes Paket Ihrer Swift-App hinzufügen
FriendlyFlix/app/FriendlyFlix/FriendlyFlix.xcodeproj
in Xcode öffnen- Wählen Sie File > Add Package Dependencies... aus.
- Klicken Sie auf Add Local... (Lokal hinzufügen…) und fügen Sie dann das
FriendlyFlixSDK
-Paket aus dem OrdnerFriendlyFlix/app
hinzu. - Warten Sie, bis Xcode die Paketabhängigkeiten aufgelöst hat.
- Wählen Sie im Dialogfeld Choose Package Products for FriendlyFlixSDK (Paketprodukte für FriendlyFlixSDK auswählen)
FriendlyFlix
als Ziel aus und klicken Sie auf Add Package (Paket hinzufügen).
iOS-App für die Verwendung des lokalen Emulators konfigurieren
- Öffnen Sie
FriendlyFlixApp.swift
. (Sie können CMD + Umschalt + O drücken, um das Dialogfeld Schnell öffnen zu öffnen, und dann „FriendlyFlixApp“ eingeben, um die Datei schnell zu finden.) - Firebase, Firebase Auth, Firebase Data Connect und das generierte SDK für Ihr Schema importieren
- Konfigurieren Sie Firebase im Initialisierer.
- Achten Sie darauf, dass DataConnect und Firebase Auth den lokalen Emulator verwenden.
import SwiftUI
import os
import Firebase
import FirebaseAuth
import FriendlyFlixSDK
import FirebaseDataConnect
@main
struct FriendlyFlixApp: App {
...
init() {
FirebaseApp.configure()
if useEmulator {
DataConnect.friendlyFlixConnector.useEmulator(port: 9399)
Auth.auth().useEmulator(withHost: "localhost", port: 9099)
}
authenticationService = AuthenticationService()
}
...
}
- Wählen Sie im Drop-down-Menü Ziel einen iOS-Simulator aus.
- Drücken Sie in Xcode CMD+R oder klicken Sie auf die Schaltfläche Run (Ausführen), um die App auf einem Simulator auszuführen.
4. Schema definieren und Datenbank vorab mit Daten füllen
In diesem Abschnitt definieren Sie die Struktur und die Beziehungen zwischen den wichtigsten Einheiten in der Filmanwendung in einem Schema. Entitäten wie Movie
und MovieMetaData
werden Datenbanktabellen zugeordnet. Beziehungen werden mit Firebase Data Connect und GraphQL-Schemaanweisungen hergestellt.
Wichtige Entitäten und Beziehungen
Das Datenmodell für diese Filmtracker-App besteht aus mehreren Entitäten, die Sie im Laufe dieses Codelabs erstellen. Sie erstellen zuerst die wichtigsten Entitäten und fügen dann, wenn Sie immer mehr Funktionen implementieren, die für diese Funktionen erforderlichen Entitäten hinzu.
In diesem Schritt erstellen Sie die Typen Movie
und MovieMetadata
.
Film
Der Typ Movie
definiert die Hauptstruktur für eine Filmentität, einschließlich Feldern wie title
, genre
, releaseYear
und rating
.
Fügen Sie in VS Code die Typdefinition Movie
zu dataconnect/schema/schema.gql
hinzu:
type Movie @table {
id: UUID! @default(expr: "uuidV4()")
title: String!
imageUrl: String!
releaseYear: Int
genre: String
rating: Float
description: String
tags: [String]
}
MovieMetadata
Der Typ MovieMetadata
stellt eine 1:1-Beziehung zum Typ Movie
her. Sie enthält zusätzliche Daten wie den Regisseur des Films.
Fügen Sie der Datei dataconnect/schema/schema.gql
die Tabellendefinition MovieMetadata
hinzu:
type MovieMetadata @table {
movie: Movie! @ref
director: String
}
Automatisch generierte Felder und Standardwerte
Im Schema werden Ausdrücke wie @default(expr: "uuidV4()")
verwendet, um automatisch eindeutige IDs und Zeitstempel zu generieren. Das Feld id
vom Typ Movie
wird beispielsweise automatisch mit einer UUID gefüllt, wenn ein neuer Datensatz erstellt wird.
Scheindaten für Filme und Filmdaten einfügen
Nachdem Sie das Schema definiert haben, können Sie die Datenbank jetzt mit Scheindaten für Tests vorab befüllen.
- Kopieren Sie im Finder
finish/FriendlyFlix/dataconnect/moviedata_insert.gql
in den Ordnerstart/FriendlyFlix/dataconnect
. - Öffnen Sie in VS Code
dataconnect/moviedata_insert.gql
. - Prüfen Sie, ob die Emulatoren in der Firebase Data Connect-Erweiterung ausgeführt werden.
- Oben in der Datei sollte die Schaltfläche Lokal ausführen angezeigt werden. Klicken Sie darauf, um die Testfilmdaten in Ihre Datenbank einzufügen.
- Prüfen Sie im Terminal Data Connect Execution, ob die Daten erfolgreich hinzugefügt wurden.
Nachdem Sie die Daten eingerichtet haben, fahren Sie mit dem nächsten Schritt fort, um zu erfahren, wie Sie Abfragen in Data Connect erstellen.
5. Filme abrufen und anzeigen
In diesem Abschnitt implementieren Sie eine Funktion zum Anzeigen einer Liste von Filmen.
Zuerst erfahren Sie, wie Sie eine Abfrage erstellen, mit der alle Filme aus der Tabelle movies
abgerufen werden. Firebase Data Connect generiert Code für ein typsicheres SDK, mit dem Sie die Abfrage ausführen und die abgerufenen Filme in der Benutzeroberfläche Ihrer App anzeigen können.
Abfrage „ListMovies“ definieren
Abfragen in Firebase Data Connect werden in GraphQL geschrieben. So können Sie angeben, welche Felder abgerufen werden sollen. In FriendlyFlix sind für die Bildschirme, auf denen Filme angezeigt werden, die folgenden Felder erforderlich: title
, description
, releaseYear
, rating
und imageUrl
. Da es sich um eine SwiftUI-App handelt, benötigen Sie außerdem id
, um die Identität der SwiftUI-Ansicht zu bestimmen.
Öffnen Sie in VS Code die Datei dataconnect/connector/queries.gql
und fügen Sie die Abfrage ListMovies
hinzu:
query ListMovies @auth(level: PUBLIC) {
movies {
id
title
imageUrl
releaseYear
genre
rating
tags
description
}
}
Wenn Sie die neue Abfrage testen möchten, klicken Sie auf die Schaltfläche Lokal ausführen, um die Abfrage für Ihre lokale Datenbank auszuführen. Die Liste der Filme aus der Datenbank sollte im Terminal für die Data Connect-Ausführung im Bereich Results (Ergebnisse) angezeigt werden.
Die ListMovies-Anfrage mit dem Startbildschirm der App verbinden
Nachdem Sie die Abfrage im Data Connect-Emulator getestet haben, können Sie sie in Ihrer App aufrufen.
Wenn Sie queries.gql
speichern, generiert Firebase Data Connect den Code, der der ListMovies
-Abfrage im FriendlyFlixSDK
-Paket entspricht.
Öffnen Sie in Xcode Movie+DataConnect.swift
und fügen Sie den folgenden Code hinzu, um ListMoviesQuery.Data.Movie
Movie
zuzuordnen:
import FirebaseDataConnect
import FriendlyFlixSDK
extension Movie {
init(from: ListMoviesQuery.Data.Movie) {
id = from.id
title = from.title
description = from.description ?? ""
releaseYear = from.releaseYear
rating = from.rating
imageUrl = from.imageUrl
}
}
Öffnen Sie die Datei HomeScreen.swift
und aktualisieren Sie sie mit dem folgenden Code-Snippet.
import SwiftUI
import FirebaseDataConnect
import FriendlyFlixSDK
struct HomeScreen: View {
...
private var connector = DataConnect.friendlyFlixConnector
let heroMoviesRef: QueryRefObservation<ListMoviesQuery.Data, ListMoviesQuery.Variables>
init() {
heroMoviesRef = connector.listMoviesQuery.ref()
}
}
extension HomeScreen {
...
private var heroMovies: [Movie] {
heroMoviesRef.data?.movies.map(Movie.init) ?? []
}
private var topMovies: [Movie] {
heroMoviesRef.data?.movies.map(Movie.init) ?? []
}
private var watchList: [Movie] {
heroMoviesRef.data?.movies.map(Movie.init) ?? []
}
...
}
Die |
Anwendung ausführen
Klicken Sie in Xcode auf die Schaltfläche Run (Ausführen), um die App im iOS-Simulator zu starten.
Nach dem Start der App sollte ein Bildschirm wie dieser angezeigt werden:
Möglicherweise wird in allen Bereichen der App (Hero-Bereich, Top-Filme und Watchlist) dieselbe Liste angezeigt. Das liegt daran, dass Sie für alle diese Datenansichten dieselbe Abfrage verwenden. In den nächsten Abschnitten implementieren Sie benutzerdefinierte Abfragen. |
6. Hero- und Top-Filme anzeigen
In diesem Schritt konzentrieren Sie sich darauf, die Darstellung von Filmen im Hero-Bereich – dem prominenten Karussell oben auf dem Startbildschirm – und im Bereich „Top-Filme“ darunter zu aktualisieren.
Derzeit werden mit der Abfrage „ListMovies“ alle Filme abgerufen. Um die Anzeige für diese Abschnitte zu optimieren, begrenzen Sie die Anzahl der Filme, die bei jeder Anfrage zurückgegeben werden. Die aktuelle Implementierung der ListMovies
-Abfrage bietet noch keine integrierte Unterstützung für das Einschränken von Ergebnissen. Die Unterstützung für das Einschränken und Sortieren wird in diesem Abschnitt hinzugefügt.
Abfrage „ListMovies“ optimieren
Öffnen Sie queries.gql
und aktualisieren Sie ListMovies
so, dass die Unterstützung für das Sortieren und Begrenzen hinzugefügt wird:
query ListMovies(
$orderByRating: OrderDirection
$orderByReleaseYear: OrderDirection
$limit: Int
) @auth(level: PUBLIC) {
movies(
orderBy: [{ rating: $orderByRating }, { releaseYear: $orderByReleaseYear }]
limit: $limit
) {
id
title
description
releaseYear
rating
imageUrl
}
}
So können Sie die Anzahl der Filme, die von der Abfrage zurückgegeben werden, begrenzen und den Ergebnissatz sowohl nach Bewertung als auch nach Erscheinungsjahr sortieren.
Sobald Sie diese Datei speichern, wird der Code in FriendlyFlixSDK
automatisch von Firebase Data Connect neu generiert. Im nächsten Schritt können Sie den Code in HomeScreen.swift
aktualisieren, um diese zusätzlichen Funktionen zu nutzen.
Erweiterte Abfrage in der Benutzeroberfläche verwenden
Kehren Sie zu Xcode zurück, um die erforderlichen Änderungen an HomeScreen.swift
vorzunehmen.
Aktualisieren Sie zuerst heroMoviesRef
, um die drei zuletzt veröffentlichten Filme abzurufen:
struct HomeScreen {
...
init() {
heroMoviesRef = connector.listMoviesQuery
.ref { optionalVars in
optionalVars.limit = 3
optionalVars.orderByReleaseYear = .DESC
}
}
}
Richten Sie als Nächstes eine weitere Abfrage-Referenz für die Top-Filme ein und legen Sie den Filter auf die fünf am besten bewerteten Filme fest:
struct HomeScreen {
...
let topMoviesRef: QueryRefObservation<ListMoviesQuery.Data, ListMoviesQuery.Variables>
init() {
heroMoviesRef = ...
topMoviesRef = connector.listMoviesQuery
.ref { optionalVars in
optionalVars.limit = 5
optionalVars.orderByRating = .DESC
}
}
}
Aktualisieren Sie schließlich die berechnete Eigenschaft, die das Ergebnis dieser Abfrage mit der Benutzeroberfläche verbindet:
extension HomeScreen {
...
private var topMovies: [Movie] {
topMoviesRef.data?.movies.map(Movie.init) ?? []
}
}
Demo
Führen Sie die App noch einmal aus, um die drei neuesten Filme im Hero-Bereich und die fünf am besten bewerteten Filme im Bereich „Top-Filme“ zu sehen:
7. Filmdetails und Schauspielerdetails anzeigen
Der Nutzer kann jetzt Filme ansehen. Wenn Nutzer auf eine Filmkarte tippen, werden ihnen einige Details zum Film angezeigt. Allerdings sind diese Details nicht sehr ausführlich.
Das liegt daran, dass wir nur so viele Details zu den einzelnen Filmen abgerufen haben, wie wir für die Darstellung des Hero-Bereichs und des Bereichs mit den Top-Filmen benötigen: den Filmtitel, eine kurze Beschreibung und die Bild-URL.
Auf der Seite mit den Filmdetails möchten wir weitere Informationen zum Film anzeigen. In diesem Abschnitt erweitern Sie die App so, dass auf der Detailseite die Schauspieler des Films und alle Rezensionen angezeigt werden.
Dazu sind einige Schritte erforderlich:
- Schema zur Unterstützung von Filmdarstellern und Rezensionen erweitern
- Firebase Data Connect-Abfragen zum Abrufen von Details zu einem bestimmten Film schreiben
- Ergebnisse auf dem Bildschirm mit den Filmdetails anzeigen
Schema optimieren
Öffnen Sie in VS Code dataconnect/schema/schema.gql
und fügen Sie die Schemadefinitionen für Actor
und MovieActor
hinzu.
## Actors
## An actor can participate in multiple movies; movies can have multiple actors
## Movie - Actors (or vice versa) is a many to many relationship
type Actor @table {
id: UUID!
imageUrl: String!
name: String! @col(name: "name", dataType: "varchar(30)")
}
## Join table for many-to-many relationship for movies and actors
## The 'key' param signifies the primary key(s) of this table
## In this case, the keys are [movieId, actorId], the generated fields of the reference types [movie, actor]
type MovieActor @table(key: ["movie", "actor"]) {
## @ref creates a field in the current table (MovieActor) that holds the primary key of the referenced type
## In this case, @ref(fields: "id") is implied
movie: Movie!
## movieId: UUID! <- this is created by the implied @ref, see: implicit.gql
actor: Actor!
## actorId: UUID! <- this is created by the implied @ref, see: implicit.gql
role: String! ## "main" or "supporting"
}
Scheindaten für Akteure hinzufügen
Nachdem das Schema aktualisiert wurde, können Sie die Datenbank jetzt mit weiteren Scheindaten für Tests füllen.
- Kopieren Sie im Finder
finish/FriendlyFlix/dataconnect/moviededetails_insert.gql
in den Ordnerstart/FriendlyFlix/dataconnect
. - Öffnen Sie in VS Code
dataconnect/moviededetails_insert.gql
. - Prüfen Sie, ob die Emulatoren in der Firebase Data Connect-Erweiterung ausgeführt werden.
- Oben in der Datei sollte die Schaltfläche Lokal ausführen angezeigt werden. Klicken Sie darauf, um die Testfilmdaten in Ihre Datenbank einzufügen.
- Prüfen Sie im Terminal für die Data Connect-Ausführung, ob die Daten erfolgreich hinzugefügt wurden.
Nachdem die Daten vorhanden sind, fahren Sie mit dem nächsten Schritt fort, um die Abfrage zum Abrufen der Filmdetails zu definieren.
Die Abfrage „GetMovieById“ definieren
Öffnen Sie in VS Code die Datei dataconnect/connector/queries.gql
und fügen Sie die Abfrage GetMovieById
hinzu:
## Get movie by id
query GetMovieById($id: UUID!) @auth(level: PUBLIC) {
movie(id: $id) {
id
title
imageUrl
releaseYear
genre
rating
description
tags
metadata: movieMetadatas_on_movie {
director
}
mainActors: actors_via_MovieActor(where: { role: { eq: "main" } }) {
id
name
imageUrl
}
supportingActors: actors_via_MovieActor(
where: { role: { eq: "supporting" } }
) {
id
name
imageUrl
}
}
}
Die Abfrage „GetMovieById“ mit der „MovieDetailsView“ verbinden
Öffnen Sie in Xcode die Datei MovieDetailsView.swift
und aktualisieren Sie die berechnete Eigenschaft movieDetails
mit dem folgenden Code:
import NukeUI
import SwiftUI
import FirebaseDataConnect
import FriendlyFlixSDK
@MainActor
struct MovieDetailsView: View {
private var movie: Movie
private var movieDetails: MovieDetails? {
DataConnect.friendlyFlixConnector
.getMovieByIdQuery
.ref(id: movie.id)
.data?.movie.map { movieDetails in
MovieDetails(
title: movieDetails.title,
description: movieDetails.description ?? "",
releaseYear: movieDetails.releaseYear,
rating: movieDetails.rating ?? 0,
imageUrl: movieDetails.imageUrl,
mainActors: movieDetails.mainActors.map { mainActor in
MovieActor(id: mainActor.id,
name: mainActor.name,
imageUrl: mainActor.imageUrl)
},
supportingActors: movieDetails.supportingActors.map{ supportingActor in
MovieActor(id: supportingActor.id,
name: supportingActor.name,
imageUrl: supportingActor.imageUrl)
},
reviews: []
)
}
}
public init(movie: Movie) {
self.movie = movie
}
}
Anwendung ausführen
Klicken Sie in Xcode auf die Schaltfläche Run (Ausführen), um die App im iOS-Simulator zu starten.
Tippe nach dem Starten der App auf eine Filmkarte, um die Filmdetails aufzurufen. Das sollte so aussehen:
8. Nutzerauthentifizierung implementieren
Derzeit werden in der App nicht personalisierte Informationen zu Filmen und Schauspielern angezeigt. In den folgenden Schritten implementieren Sie Funktionen, mit denen Daten dem angemeldeten Nutzer zugeordnet werden. Zuerst ermöglichen Sie Nutzern, Filme zu ihrer persönlichen Merkliste hinzuzufügen.
Bevor Sie die Funktion „Beobachtungsliste“ implementieren können, müssen Sie zuerst die Nutzeridentität feststellen. Dazu müssen Sie Firebase Authentication einbinden, damit sich Nutzer in der App anmelden können.
Vielleicht haben Sie die Schaltfläche mit dem Nutzeravatar oben rechts auf dem Startbildschirm schon gesehen. Wenn Sie darauf tippen, gelangen Sie zu einem Bildschirm, auf dem sich Nutzer mit ihrer E-Mail-Adresse und ihrem Passwort registrieren oder anmelden können.
Nachdem sich ein Nutzer erfolgreich angemeldet hat, muss Ihre App seine wichtigsten Daten speichern, vor allem seine eindeutige Nutzer-ID und den ausgewählten Nutzernamen.
Firebase Authentication aktivieren
Rufen Sie in der Firebase Console für Ihr Projekt den Bereich „Authentifizierung“ auf und aktivieren Sie Firebase Authentication. Aktivieren Sie dann den Authentifizierungsanbieter für E-Mail-Adresse/Passwort.
Suchen Sie in Ihrem lokalen Projektordner nach firebase.json
und aktualisieren Sie die Datei wie unten beschrieben, um den Firebase Authentication-Emulator zu aktivieren.
{
"emulators": {
"dataconnect": {
},
"auth": {
}
},
"dataconnect": {
"source": "dataconnect"
}
}
Danach müssen Sie den Firebase-Emulator beenden und neu starten, damit die Änderung wirksam wird.
Authentifizierungs-Handler implementieren
Im folgenden Abschnitt implementieren Sie die Logik, die die Nutzerauthentifizierung mit Ihrer Datenbank verbindet. Dazu müssen Sie einen Authentifizierungs-Handler erstellen, der auf erfolgreiche Anmeldungen wartet.
Sobald ein Nutzer authentifiziert ist, wird durch diesen Handler automatisch das entsprechende Konto in Ihrer Datenbank erstellt.
Öffnen Sie in Xcode die Datei AuthenticationService.swift
und fügen Sie den folgenden Code ein:
import Foundation
import Observation
import os
import FirebaseAuth
enum AuthenticationState {
case unauthenticated
case authenticating
case authenticated
}
@Observable
class AuthenticationService {
private let logger = Logger(subsystem: "FriendlyFlix", category: "auth")
var presentingAuthenticationDialog = false
var presentingAccountDialog = false
var authenticationState: AuthenticationState = .unauthenticated
var user: User?
private var authenticationListener: AuthStateDidChangeListenerHandle?
init() {
authenticationListener = Auth.auth().addStateDidChangeListener { auth, user in
if let user {
self.authenticationState = .authenticated
self.user = user
} else {
self.authenticationState = .unauthenticated
}
}
}
private var onSignUp: ((User) -> Void)?
public func onSignUp(_ action: @escaping (User) -> Void) {
onSignUp = action
}
func signInWithEmailPassword(email: String, password: String) async throws {
try await Auth.auth().signIn(withEmail: email, password: password)
authenticationState = .authenticated
}
func signUpWithEmailPassword(email: String, password: String) async throws {
try await Auth.auth().createUser(withEmail: email, password: password)
if let onSignUp, let user = Auth.auth().currentUser {
logger
.debug(
"User signed in \(user.displayName ?? "(no fullname)") with email \(user.email ?? "(no email)")"
)
onSignUp(user)
}
authenticationState = .authenticated
}
func signOut() throws {
try Auth.auth().signOut()
authenticationState = .unauthenticated
}
}
Dies ist ein generischer Authentifizierungshandler, mit dem Sie mit onSignUp
einen Abschluss registrieren können, der aufgerufen wird, wenn sich der Nutzer angemeldet hat.
Innerhalb dieses Closure können Sie dann ein neues Nutzerkonto in der Datenbank erstellen. Bevor Sie das tun können, müssen Sie jedoch eine Mutation erstellen, mit der Sie neue Nutzer in der Datenbank erstellen oder aktualisieren können.
Nutzerentität dem Schema hinzufügen
Der Typ User
definiert eine Nutzerentität. Nutzer können mit Filmen interagieren, indem sie Rezensionen schreiben oder Filme als Favoriten markieren.
Öffnen Sie in VS Code die Datei dataconnect/schema/schema.gql
und fügen Sie die folgende User
-Tabellendefinition hinzu:
## Users
## A user can leave reviews for movies
## user-reviews is a one to many relationship, movie-reviews is a one to many relationship, movie:user is a many to many relationship
type User @table {
id: String! @col(name: "user_auth")
username: String! @col(name: "username", dataType: "varchar(50)")
}
Mutation zum Einfügen oder Aktualisieren eines Nutzers definieren
Öffnen Sie in VS Code die Datei dataconnect/connector/mutations.gql
und fügen Sie die Mutation UpsertUser
hinzu:
mutation UpsertUser($username: String!) @auth(level: USER) {
user_upsert(
data: {
id_expr: "auth.uid"
username: $username
}
)
}
Neuen Nutzer nach erfolgreicher Anmeldung erstellen
Öffnen Sie in Xcode FriendlyFlixApp.swift
und fügen Sie dem Initialisierer den folgenden Code hinzu:
@main
struct FriendlyFlixApp: App {
...
init() {
...
authenticationService = AuthenticationService()
authenticationService?.onSignUp { user in
let userName = String(user.email?.split(separator: "@").first ?? "(unknown)")
Task {
try await DataConnect.friendlyFlixConnector
.upsertUserMutation.execute(username: userName)
}
}
}
var body: some Scene {
...
}
}
In diesem Code wird der upsertUserMutation
Firebase Data Connect verwendet, der für Sie generiert wurde, um einen neuen Nutzer einzufügen (oder einen vorhandenen Nutzer mit derselben ID zu aktualisieren), wenn sich ein Nutzer erfolgreich mit Firebase Authentication registriert hat.
Demo
So prüfen Sie, ob das funktioniert:
- Falls nicht, beenden Sie den Firebase-Emulator und starten Sie ihn neu, um sicherzustellen, dass der Firebase Authentication-Emulator ausgeführt wird.
- Klicken Sie in Xcode auf die Schaltfläche Run (Ausführen), um die App im iOS-Simulator zu starten.
- Klicken Sie oben rechts auf dem Bildschirm auf das Avatarsymbol.
- Wechseln Sie zum Ablauf Registrieren und registrieren Sie sich für die App.
Fragen Sie dann die Datenbank ab, um zu prüfen, ob die App ein neues Nutzerkonto für den Nutzer erstellt hat:
- Öffnen Sie
dataconnect/schema/schema.gql
in VS Code und klicken Sie für dieUser
-Entität auf Daten lesen. - Dadurch wird eine neue Abfragedatei mit dem Namen
User_read.gql
erstellt. - Klicken Sie auf Lokal ausführen, um alle Nutzer in der Nutzertabelle zu sehen.
- Im Bereich „Data Connect Execution“ (Data Connect-Ausführung) sollte jetzt ein Konto für den Nutzer angezeigt werden, mit dem Sie sich gerade registriert haben
9. Lieblingsfilme verwalten
In diesem Abschnitt des Codelabs implementieren Sie Nutzerinteraktionen in der Filmrezensions-App. Nutzer sollen insbesondere ihre Lieblingsfilme verwalten können. Als Favoriten markierte Filme werden im Bereich „Merkliste“ der App angezeigt.
Schema zur Unterstützung von Favoriten erweitern
Der Typ FavoriteMovie
ist eine Join-Tabelle, in der Viele-zu-viele-Beziehungen zwischen Nutzern und ihren Lieblingsfilmen verwaltet werden. In jeder Tabelle wird ein User
mit einem Movie
verknüpft.
Kopieren Sie das Code-Snippet und fügen Sie es in Ihre dataconnect/schema/schema.gql
-Datei ein:
type FavoriteMovie
@table(name: "FavoriteMovies", singular: "favorite_movie", plural: "favorite_movies", key: ["user", "movie"]) {
## @ref is implicit
user: User!
movie: Movie!
}
Mutationen zum Hinzufügen und Entfernen von Favoriten definieren
Bevor die App die Lieblingsfilme des Nutzers anzeigen kann, muss der Nutzer angeben, welche Filme seine Favoriten sind. Dazu müssen Sie zuerst zwei Mutationen hinzufügen, um einen Film als Favorit des Nutzers zu markieren oder ihn wieder aus seinen Favoriten zu entfernen.
- Öffnen Sie in VS Code
mutations.gql
indataconnect/connector/mutations.gql
. - Fügen Sie die folgenden Mutationen hinzu, um das Markieren von Filmen als Favoriten zu ermöglichen:
## Add a movie to the user's favorites list
mutation AddFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId })
}
## Remove a movie from the user's favorites list
mutation DeleteFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
}
Mutationen mit der Benutzeroberfläche Ihrer App verbinden
Nutzer können einen Film als Favorit markieren, indem sie auf dem Detailbildschirm des Films auf das Herzsymbol klicken.
Damit die gerade erstellten Mutationen mit der Benutzeroberfläche der App verbunden werden, nehmen Sie die folgenden Änderungen in MovieCardView
vor:
FriendlyFlixSDK
importieren und Connector einrichten
import NukeUI
import os
import SwiftUI
import FirebaseDataConnect
import FriendlyFlixSDK
struct MovieCardView: View {
private let logger = Logger(subsystem: "FriendlyFlix", category: "moviecard")
@Environment(\.dismiss) private var dismiss
private var connector = DataConnect.friendlyFlixConnector
...
}
- Implementieren Sie die Methode
toggleFavourite
. Sie wird immer aufgerufen, wenn der Nutzer inMovieCardView
auf das Herzsymbol tippt:
struct MovieCardView {
...
private func toggleFavourite() {
Task {
if isFavourite {
let _ = try await connector.deleteFavoritedMovieMutation.execute(movieId: movie.id)
} else {
let _ = try await connector.addFavoritedMovieMutation.execute(movieId: movie.id)
}
}
}
}
Dadurch wird der Favoritenstatus des aktuellen Films in der Datenbank aktualisiert. Ein letzter Schritt fehlt noch: Der UI-Status muss entsprechend aktualisiert werden.
Abfrage definieren, um herauszufinden, ob ein Film als Favorit markiert ist
- Öffnen Sie in VS Code
queries.gql
indataconnect/connector
. - Fügen Sie die folgende Abfrage hinzu, um zu prüfen, ob ein Film als Favorit markiert ist:
query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) {
movieId
}
}
- Instanziieren Sie in Xcode eine Referenz auf die
GetIfFavoritedMovie
-Abfrage und implementieren Sie die berechnete Eigenschaft, die bestimmt, ob der auf dieserMovieCardView
angezeigte Film für den aktuellen Nutzer als Favorit markiert ist.
struct MovieCardView: View {
...
public init(showDetails: Bool, movie: Movie) {
self.showDetails = showDetails
self.movie = movie
isFavouriteRef = connector.getIfFavoritedMovieQuery.ref(movieId: movie.id)
}
// MARK: - Favourite handling
private let isFavouriteRef: QueryRefObservation<
GetIfFavoritedMovieQuery.Data,
GetIfFavoritedMovieQuery.Variables
>
private var isFavourite: Bool {
isFavouriteRef.data?.favorite_movie?.movieId != nil
}
...
}
- Aktualisieren Sie den Code in
toggleFavourite
, damit die Abfrage ausgeführt wird, wenn der Nutzer auf die Schaltfläche tippt. So wird sichergestellt, dass die berechnete PropertyisFavourite
immer den richtigen Wert zurückgibt.
private func toggleFavourite() {
Task {
if isFavourite {
...
}
let _ = try await isFavouriteRef.execute()
}
}
Lieblingsfilme abrufen
Als letzten Schritt für diese Funktion müssen Sie die Lieblingsfilme des Nutzers abrufen, damit er sie auf seiner Watchlist sehen kann.
- Öffnen Sie in VS Code
queries.gql
indataconnect/connector/queries.gql
und fügen Sie die folgende Abfrage ein:
## Get favorite movies by user ID
query GetUserFavoriteMovies @auth(level: USER) {
user(id_expr: "auth.uid") {
favoriteMovies: favorite_movies_on_user {
movie {
id
title
genre
imageUrl
releaseYear
rating
description
}
}
}
}
Die Liste der Lieblingsfilme des Nutzers wird auf der LibraryScreen
angezeigt. Auf diesem Bildschirm sollten nur Daten angezeigt werden, wenn der Nutzer angemeldet ist. Verbinden Sie daher zuerst den Authentifizierungsstatus des Bildschirms mit dem AuthenticationService
der App.
- Fügen Sie Code hinzu, um
FavoriteMovieFavoriteMovies
,Movie
undMovie+DataConnect.swift
zuzuordnen:
import FirebaseDataConnect
import FriendlyFlixSDK
extension Movie {
...
init(from: GetUserFavoriteMoviesQuery.Data.User.FavoriteMovieFavoriteMovies) {
id = from.movie.id
title = from.movie.title
description = from.movie.description ?? ""
releaseYear = from.movie.releaseYear
rating = from.movie.rating
imageUrl = from.movie.imageUrl
}
}
- Öffnen Sie in Xcode
LibraryScreen
und aktualisieren SieisSignedIn
so:
struct LibraryScreen: View {
...
private var isSignedIn: Bool {
authenticationService.user != nil
}
}
- Importieren Sie dann Firebase Data Connect und FriendlyFlixSDK und rufen Sie eine Referenz auf die
GetUserFavoriteMovies
-Abfrage ab:
import SwiftUI
import FirebaseDataConnect
import FriendlyFlixSDK
struct LibraryScreen {
...
private var connector = DataConnect.friendlyFlixConnector
...
init() {
watchListRef = connector.getUserFavoriteMoviesQuery.ref()
}
private let watchListRef: QueryRefObservation<
GetUserFavoriteMoviesQuery.Data,
GetUserFavoriteMoviesQuery.Variables
>
private var watchList: [Movie] {
watchListRef.data?.user?.favoriteMovies.map(Movie.init) ?? []
}
...
}
- Prüfen Sie, ob die
watchListRef
-Abfrage ausgeführt wird, wenn die Ansicht angezeigt wird:
extension LibraryScreen: View {
var body: some View {
...
MovieListSection(namespace: namespace, title: "Watch List", movies: watchList)
.onAppear {
Task {
try await watchListRef.execute()
}
...
Demo
Sie können die App jetzt ausführen und die gerade implementierte Favoritenfunktion ausprobieren. Beachten Sie Folgendes:
- Prüfen, ob der Firebase-Emulator ausgeführt wird
- Achten Sie darauf, dass Sie Mock-Daten für die Filme und Filmdetails hinzugefügt haben.
- Sie müssen sich als Nutzer registriert haben.
- Klicken Sie in Xcode auf die Schaltfläche Run (Ausführen), um die App im iOS-Simulator zu starten.
- Tippe nach dem Starten der App auf eine Filmkarte, um die Filmdetails aufzurufen.
- Tippe auf das Herzsymbol, um den Film als Favorit zu markieren. Das Herz sollte durchgehend gefüllt sein.
- Wiederhole diesen Vorgang für einige Filme.
- Gehe zum Tab „Mediathek“. Sie sollten jetzt eine Liste aller Filme sehen, die Sie als Favoriten markiert haben.
10. Glückwunsch
Herzlichen Glückwunsch, Sie haben Firebase Data Connect erfolgreich zu einer iOS-App hinzugefügt. Sie kennen nun die wichtigsten Schritte, die zum Einrichten von Data Connect, zum Erstellen von Abfragen und Mutationen sowie zum Verarbeiten der Nutzerauthentifizierung erforderlich sind.
Optional: In der Produktion bereitstellen
Bisher wurden in dieser App nur die Firebase-Emulatoren verwendet. Wenn Sie wissen möchten, wie Sie diese App in einem echten Firebase-Projekt bereitstellen, fahren Sie mit dem nächsten Schritt fort.
11. (Optional) Anwendung bereitstellen
Bisher war diese App vollständig lokal. Alle Daten sind in der Firebase Emulator Suite enthalten. In diesem Abschnitt erfahren Sie, wie Sie Ihr Firebase-Projekt so konfigurieren, dass diese App in der Produktion funktioniert.
Firebase Authentication aktivieren
- Rufen Sie in der Firebase Console den Abschnitt Authentifizierung auf und klicken Sie auf Jetzt starten.
- Rufen Sie den Tab Anmeldemethode auf .
- Wählen Sie im Bereich „Native Anbieter“ die Option „E-Mail/Passwort“ aus.
- Aktivieren Sie den Anbieter für E-Mail-Adresse/Passwort und klicken Sie dann auf Speichern.
Firebase Data Connect aktivieren
Wichtig: Wenn Sie zum ersten Mal ein Schema in Ihrem Projekt bereitstellen, wird bei diesem Vorgang eine Cloud SQL for PostgreSQL-Instanz erstellt. Das kann etwa 15 Minuten dauern. Sie können die Funktion erst bereitstellen, wenn die Cloud SQL-Instanz bereit und in Firebase Data Connect eingebunden ist.
1. Klicken Sie in der Benutzeroberfläche der VS Code-Erweiterung „Firebase Data Connect“ auf Deploy to production (In Produktion bereitstellen). 2. Möglicherweise müssen Sie Schemaänderungen überprüfen und potenziell destruktive Änderungen genehmigen. Sie werden aufgefordert, - Schemaänderungen mit firebase dataconnect:sql:diff
zu prüfen. - Wenn Sie mit den Änderungen zufrieden sind, wenden Sie sie mit dem von firebase dataconnect:sql:migrate
gestarteten Ablauf an.
Ihre Cloud SQL for PostgreSQL-Instanz wird mit dem endgültigen bereitgestellten Schema und den endgültigen bereitgestellten Daten aktualisiert. Sie können den Status in der Firebase Console überwachen.
Klicken Sie nun im Bereich „Firebase Data Connect“ auf „Ausführen (Produktion)“, um Daten in die Produktionsumgebung einzufügen.
Bevor Sie die iOS-App noch einmal ausführen, müssen Sie dafür sorgen, dass sie mit der Produktionsinstanz Ihres Projekts verbunden ist:
- Öffnen Sie das Menü Produkt > Schema > Schema bearbeiten….
- Entfernen Sie im Bereich Ausführen das Häkchen für das Startargument
-useEmulator YES
.