1. Übersicht
In diesem Codelab erfahren Sie, wie Sie Firebase Data Connect in eine Cloud SQL-Datenbank einbinden, um mit SwiftUI eine App für Filmbewertungen für iOS zu erstellen.
Sie erfahren, wie Sie Ihre iOS-Anwendung mithilfe von Firebase Data Connect mit einer Cloud SQL-Datenbank verbinden, um eine nahtlose Datensynchronisierung für Filmrezensionen zu ermöglichen.
Am Ende dieses Codelabs haben Sie eine funktionsfähige iOS-App, mit der Nutzer Filme durchsuchen und als Favoriten markieren können. Die App wird von einer Cloud SQL-Datenbank mit Firebase Data Connect unterstützt.
Lerninhalte
In diesem Codelab lernen Sie Folgendes:
- Richten Sie Firebase Data Connect mit der Firebase Emulator Suite ein, um schnell loszulegen.
- Entwerfen Sie ein Datenbankschema mit Data Connect und GraphQL.
- Erstellen Sie ein typsicheres Swift SDK aus Ihrem Datenbankschema und fügen Sie es einer Swift-Anwendung hinzu.
- Implementieren Sie die Nutzerauthentifizierung und integrieren Sie sie in Firebase Data Connect, um die Daten Ihrer Nutzer zu schützen.
- Mithilfe von Abfragen und Mutationen, die auf GraphQL basieren, können Sie Daten in Cloud SQL abrufen, aktualisieren, löschen und verwalten.
- Optional: Bereitstellen eines Data Connect-Dienstes in der Produktion.
Vorbereitung
- Die neueste Version von Xcode
- Der Beispielcode des Codelabs 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 in der Firebase Console auf Firebase-Projekt erstellen.
- Geben Sie einen Namen für Ihr Firebase-Projekt ein (z. B. „Friendly Flix“) und klicken Sie auf Weiter.
- Sie werden möglicherweise aufgefordert, die KI-Unterstützung für Ihr Firebase-Projekt zu aktivieren. Für dieses Codelab spielt Ihre Auswahl keine Rolle.
- Möglicherweise werden Sie aufgefordert, Google Analytics zu aktivieren. Für dieses Codelab spielt Ihre Auswahl keine Rolle.
- Nach etwa einer Minute ist Ihr Firebase-Projekt bereit. Klicken Sie 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/peterfriese/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 mehrmals auf Weiter, um das Einrichtungsprojekt in der Firebase Console abzuschließen. Sie müssen der App das SDK nicht hinzufügen, da dies bereits im Starterprojekt für Sie erledigt wurde.
- 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 Script versucht, die Entwicklungsumgebung für Sie einzurichten und eine browserbasierte IDE zu starten. Diese IDE bietet Tools, einschließlich einer vorkonfigurierten VS Code-Erweiterung, mit denen Sie Ihr Schema verwalten, Abfragen und Mutationen für Ihre Anwendung definieren und stark typisierte SDKs generieren können.
Nach dem Ausführen des Scripts 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
- Node.js installieren
- Öffnen Sie in VS Code das Verzeichnis
codelab-dataconnect-ios/FriendlyFlix
. - Installieren Sie die Firebase Data Connect-Erweiterung aus dem 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 verbinden 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 bedeutet:
connectorId
: Ein eindeutiger Name für diesen Connector.outputDir
: Pfad, unter dem das generierte Data Connect SDK gespeichert wird. Dieser Pfad ist relativ zum Verzeichnis, das die Dateiconnector.yaml
enthält.package
: Der Paketname, der für das generierte Swift-Paket verwendet werden soll.
Nachdem Sie diese Datei gespeichert haben, 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 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>
Das generierte Paket Ihrer Swift-App hinzufügen
FriendlyFlix/app/FriendlyFlix/FriendlyFlix.xcodeproj
in Xcode öffnen- Wählen Sie Datei > Paketabhängigkeiten hinzufügen… aus.
- Klicken Sie auf Lokales hinzufügen… und fügen Sie das
FriendlyFlixSDK
-Paket aus dem OrdnerFriendlyFlix/app
hinzu. - Warten Sie, bis Xcode die Paketabhängigkeiten aufgelöst hat.
- Wähle im Dialogfeld Choose Package Products for FriendlyFlixSDK (Paketprodukte für FriendlyFlixSDK auswählen)
FriendlyFlix
als Ziel aus und klicke auf Add Package (Paket hinzufügen).
iOS-App für die Verwendung des lokalen Emulators konfigurieren
- Öffnen Sie
FriendlyFlixApp.swift
. Sie können CMD + Umschalttaste + 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 die Tastenkombination CMD+R (oder klicken Sie auf die Schaltfläche Ausführen), um die App in einem Simulator auszuführen.
4. Schema definieren und Datenbank vorab befüllen
In diesem Abschnitt definieren Sie die Struktur und die Beziehungen zwischen den wichtigsten Entitäten in der Filmanwendung in einem Schema. Entitäten wie Movie
und MovieMetaData
werden Datenbanktabellen zugeordnet. Die Beziehungen werden mithilfe von Firebase Data Connect- und GraphQL-Schemarichtlinien hergestellt.
Wichtige Entitäten und Beziehungen
Das Datenmodell für diese Film-Tracker-App besteht aus mehreren Entitäten, die Sie im Laufe dieses Codelabs erstellen. Sie erstellen zuerst die Hauptentitäten und fügen nach und nach die für die einzelnen Funktionen erforderlichen Entitäten hinzu.
In diesem Schritt erstellen Sie die Typen Movie
und MovieMetadata
.
Film
Der Typ Movie
definiert die Hauptstruktur einer Filmentität, einschließlich Feldern wie title
, genre
, releaseYear
und rating
.
Fügen Sie in VS Code dataconnect/schema/schema.gql
die Typdefinition Movie
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 Eins-zu-eins-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. Beispielsweise wird das Feld id
vom Typ Movie
beim Erstellen eines neuen Eintrags automatisch mit einer UUID ausgefüllt.
Mock-Daten für Filme und Filmmetadaten einfügen
Nachdem Sie das Schema definiert haben, können Sie die Datenbank jetzt mit Testdaten füllen.
- Kopieren Sie
finish/FriendlyFlix/dataconnect/moviedata_insert.gql
im Finder 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 Ausführen (lokal) angezeigt werden. Klicken Sie darauf, um die simulierten Filmdaten in Ihre Datenbank einzufügen.
- Prüfen Sie im Terminal Data Connect Execution, ob die Daten erfolgreich hinzugefügt wurden.
Nachdem Sie die Daten importiert 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 lernen 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 die id
für die SwiftUI-Ansichtsidentität.
Ö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
}
}
Klicken Sie zum Testen der neuen Abfrage auf die Schaltfläche Ausführen (lokal), um die Abfrage in Ihrer lokalen Datenbank auszuführen. Die Liste der Filme aus der Datenbank sollte im Bereich Ergebnisse des Data Connect Execution-Terminals angezeigt werden.
Die Abfrage „ListMovies“ mit dem Startbildschirm der App verknüpfen
Nachdem Sie die Abfrage im Data Connect-Emulator getestet haben, können Sie sie von Ihrer App aus 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
zu 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 Abfrage |
Anwendung ausführen
Klicken Sie in Xcode auf die Schaltfläche Ausführen, um die App im iOS-Simulator zu starten.
Nach dem Starten der App sollte ein Bildschirm wie dieser angezeigt werden:
Sie werden feststellen, dass in allen Bereichen der App (Hero-Bereich, Top-Filme und Merkliste) dieselbe Liste angezeigt wird. 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 zu aktualisieren – das ist das auffällige Karussell oben auf dem Startbildschirm – und auch im Bereich „Top-Filme“ unten.
Derzeit werden mit der Abfrage „ListMovies“ alle Filme abgerufen. Um die Darstellung für diese Bereiche zu optimieren, begrenzen Sie die Anzahl der Filme, die bei jeder Abfrage zurückgegeben werden. Die aktuelle Implementierung der ListMovies
-Abfrage bietet noch keine integrierte Unterstützung für die Begrenzung von Ergebnissen. In diesem Abschnitt fügen Sie die Unterstützung für die Begrenzung und Sortierung hinzu.
ListMovies-Abfrage verbessern
Öffnen Sie queries.gql
und aktualisieren Sie ListMovies
so, dass die Sortierung und Begrenzung unterstützt 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 begrenzen, die von der Abfrage zurückgegeben werden, und den Ergebnissatz sowohl nach Altersfreigabe als auch nach Erscheinungsjahr sortieren.
Nachdem Sie diese Datei gespeichert haben, wird der Code innerhalb von 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.
Aktualisiere 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 Abfragereferenz für die Top-Filme ein und legen Sie den Filter auf die fünf Filme mit der höchsten Bewertung 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 abschließend das berechnete Attribut, das das Ergebnis dieser Abfrage mit der Benutzeroberfläche verbindet:
extension HomeScreen {
...
private var topMovies: [Movie] {
topMoviesRef.data?.movies.map(Movie.init) ?? []
}
}
Beispiele ansehen
Starten Sie die App noch einmal, um die drei neuesten Filme im Hero-Bereich und die fünf bestbewerteten Filme im Bereich „Top-Filme“ zu sehen:
7. Film- und Schauspielerdetails anzeigen
Der Nutzer kann jetzt Filme durchsuchen. Wenn du auf eine Filmkarte tippst, werden dir einige Details zum Film angezeigt. Du hast aber vielleicht schon bemerkt, dass diese Details nicht wirklich detailliert sind.
Das liegt daran, dass wir nur so viele Details zu jedem Film abgerufen haben, wie für die Darstellung des Hero-Bereichs und des Bereichs „Top-Filme“ erforderlich waren: den Filmtitel, eine kurze Beschreibung und die Bild-URL.
Auf der Detailseite des Films möchten wir weitere Informationen zum Film anzeigen. In diesem Abschnitt erweitern Sie die App, damit auf der Detailseite die Schauspieler des Films und alle Rezensionen angezeigt werden können.
Dazu sind einige Schritte erforderlich:
- Schema zur Unterstützung von Filmschauspielern und Rezensionen erweitert
- Firebase Data Connect-Abfragen zum Abrufen von Details zu einem bestimmten Film schreiben
- Ergebnisse auf dem Bildschirm mit Filmdetails anzeigen
Schema optimieren
Öffnen Sie dataconnect/schema/schema.gql
in VS Code 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"
}
Mock-Daten für Nutzer hinzufügen
Nachdem das Schema aktualisiert wurde, können Sie die Datenbank jetzt mit weiteren Mock-Daten für Tests füllen.
- Kopieren Sie
finish/FriendlyFlix/dataconnect/moviededetails_insert.gql
im Finder 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 Ausführen (lokal) angezeigt werden. Klicken Sie darauf, um die simulierten Filmdaten in Ihre Datenbank einzufügen.
- Prüfen Sie im Terminal für die Ausführung von Data Connect, ob die Daten erfolgreich hinzugefügt wurden.
Nachdem Sie die Daten zusammengestellt haben, fahren Sie mit dem nächsten Schritt fort, um die Abfrage zu definieren, mit der die Filmdetails abgerufen werden sollen.
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 Datenansicht „MovieDetailsView“ verknüpfen
Öffnen Sie in Xcode die Datei MovieDetailsView.swift
und aktualisieren Sie die berechnete Eigenschaft movieDetails
so, dass sie dem folgenden Code entspricht:
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 Ausführen, um die App im iOS-Simulator zu starten.
Tippe nach dem Start 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 erlauben 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 integrieren Sie Firebase Authentication, damit sich Nutzer in der App anmelden können.
Möglicherweise haben Sie die Schaltfläche für den Nutzeravatar bereits oben rechts auf dem Startbildschirm 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.
Sobald sich ein Nutzer erfolgreich angemeldet hat, muss Ihre App seine wichtigsten Details speichern, vor allem seine eindeutige Nutzer-ID und den ausgewählten Nutzernamen.
Firebase Authentication aktivieren
Aktivieren Sie in der Firebase Console für Ihr Projekt die Firebase-Authentifizierung. Aktivieren Sie dann den E-Mail-/Passwort-Authentifizierungsanbieter.
Suchen Sie in Ihrem lokalen Projektordner nach firebase.json
und aktualisieren Sie es so, dass der Firebase Authentication-Emulator aktiviert wird.
{
"emulators": {
"dataconnect": {
},
"auth": {
}
},
"dataconnect": {
"source": "dataconnect"
}
}
Anschließend 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 über 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 hinzu:
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 Authentifizierungs-Handler, mit dem du über onSignUp
ein Schließen registrieren kannst, das aufgerufen wird, wenn sich der Nutzer angemeldet hat.
Innerhalb dieses Abschlusses können Sie dann ein neues Nutzerkonto in der Datenbank erstellen. Bevor Sie dies tun können, müssen Sie eine Mutation erstellen, mit der Sie neue Nutzer in der Datenbank erstellen oder aktualisieren können.
Dem Schema eine Nutzerentität hinzufügen
Der Typ User
definiert eine Nutzerentität. Nutzer können mit Filmen interagieren, indem sie Rezensionen verfassen oder Filme zu ihren Favoriten hinzufügen.
Ö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
}
)
}
Nach der Anmeldung einen neuen Nutzer erstellen
Öffnen Sie in Xcode FriendlyFlixApp.swift
und fügen Sie der Initialisiererfunktion 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 das für Sie generierte upsertUserMutation
Firebase Data Connect verwendet, um einen neuen Nutzer einzufügen oder einen vorhandenen Nutzer mit derselben ID zu aktualisieren, wenn sich ein Nutzer mit Firebase Authentication erfolgreich registriert hat.
Beispiele ansehen
Melden Sie sich zuerst in der iOS-App an, um zu prüfen, ob das funktioniert:
- Falls nicht, beenden Sie den Firebase-Emulator und starten Sie ihn neu, damit der Firebase Authentication-Emulator ausgeführt wird.
- Klicken Sie in Xcode auf die Schaltfläche Ausführen, um die App im iOS-Simulator zu starten.
- Klicken Sie oben rechts auf dem Bildschirm auf das Avatarsymbol.
- Wechseln Sie zum Registrierungsvorgang und registrieren Sie sich in der App.
Rufen Sie dann die Datenbank ab, um zu prüfen, ob die App ein neues Nutzerkonto für den Nutzer erstellt hat:
- Öffnen Sie in VS Code
dataconnect/schema/schema.gql
und klicken Sie bei der EntitätUser
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 Filmbewertungs-App, damit Nutzer ihre Lieblingsfilme verwalten können. Als Favoriten markierte Filme werden in der App im Bereich „Merkliste“ angezeigt.
Schema für die Unterstützung von Favoriten erweitern
Der Typ FavoriteMovie
ist eine Join-Tabelle, die Mehrfachbeziehungen zwischen Nutzern und ihren Lieblingsfilmen verarbeitet. Jede Tabelle verknüpft eine User
mit einer Movie
.
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 er angeben, welche Filme das sind. Dazu müssen Sie zuerst zwei Mutationen hinzufügen, um einen Film als einen der Favoriten des Nutzers zu kennzeichnen 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 Filme zu den Favoriten hinzuzufügen:
## 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 verknüpfen
Nutzer können einen Film als Favoriten markieren, indem sie auf dem Detailbildschirm des Films auf das Herzsymbol klicken.
Um die von Ihnen erstellten Mutationen mit der Benutzeroberfläche der App zu verknüpfen, nehmen Sie in MovieCardView
die folgenden Änderungen 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 aufgerufen, wenn der Nutzer in derMovieCardView
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: Sie müssen dafür sorgen, dass der UI-Status entsprechend widergespiegelt wird.
Abfrage definieren, um herauszufinden, ob ein Film als Favorit markiert ist
- Öffnen Sie in VS Code
queries.gql
indataconnect/connector
. - Füge 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
}
}
- Erstelle in Xcode eine Referenz auf die
GetIfFavoritedMovie
-Abfrage und implementiere die berechnete Eigenschaft, die angibt, ob der in 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 jedes Mal 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 implementieren Sie das Abrufen der Lieblingsfilme der Nutzer, damit sie diese auf ihrer Merkliste sehen können.
- Ö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. Sie verbinden daher zuerst den Authentifizierungsstatus des Bildschirms mit der AuthenticationService
der App.
- Fügen Sie Code hinzu, um von
FavoriteMovieFavoriteMovies
nachMovie
und dann nachMovie+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 Sie dannisSignedIn
so:
struct LibraryScreen: View {
...
private var isSignedIn: Bool {
authenticationService.user != nil
}
}
- Importiere dann Firebase Data Connect und FriendlyFlixSDK und erhalte eine Referenz auf die
GetUserFavoriteMovies
-Abfrage:
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) ?? []
}
...
}
- Achten Sie darauf, dass 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()
}
...
Beispiele ansehen
Sie können jetzt die App ausführen und die gerade implementierte Favoritenfunktion ausprobieren. Beachten Sie dabei 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 Ausführen, um die App im iOS-Simulator zu starten.
- Tippe nach dem Start der App auf eine Filmkarte, um die Filmdetails aufzurufen.
- Tippe auf das Herzsymbol, um den Film als Favoriten zu markieren. Das Herz sollte jetzt durchgehend angezeigt werden.
- Wiederholen Sie diesen Vorgang für einige Filme.
- Rufe den Tab „Mediathek“ auf. Es sollte jetzt eine Liste aller Filme angezeigt werden, die du als Favoriten markiert hast.
10. Glückwunsch
Herzlichen Glückwunsch, Sie haben Firebase Data Connect einer iOS-App hinzugefügt. Sie wissen jetzt, wie Sie Data Connect einrichten, Abfragen und Mutationen erstellen und die Nutzerauthentifizierung verarbeiten.
Optional: Für Produktion bereitstellen
Bisher wurden für diese 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 und alle Daten befinden sich in der Firebase Emulator Suite. In diesem Abschnitt erfahren Sie, wie Sie Ihr Firebase-Projekt so konfigurieren, dass diese App in der Produktion funktioniert.
Firebase Authentication aktivieren
- Klicken Sie in der Firebase Console im Bereich Authentifizierung 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 dabei eine Cloud SQL-PostgreSQL-Instanz erstellt. Das kann etwa 15 Minuten dauern. Sie können erst dann eine Bereitstellung vornehmen, wenn die Cloud SQL-Instanz bereit ist und mit Firebase Data Connect verknüpft wurde.
1. Klicken Sie in der Benutzeroberfläche der VS Code-Erweiterung für Firebase Data Connect auf In Produktion bereitstellen. 2. Möglicherweise müssen Sie Schemaänderungen prüfen und potenziell schädliche Änderungen genehmigen. Sie werden aufgefordert, Folgendes zu tun:firebase dataconnect:sql:diff
firebase dataconnect:sql:migrate
Ihre Cloud SQL for PostgreSQL-Instanz wird mit dem endgültig bereitgestellten Schema und den Daten aktualisiert. Sie können den Status in der Firebase Console prüfen.
Klicken Sie jetzt im Bereich „Firebase Data Connect“ auf „Ausführen (Produktion)“, genau wie bei den lokalen Emulatoren, um der Produktionsumgebung Daten hinzuzufügen.
Bevor Sie die iOS-App wieder ausführen, prüfen Sie, ob eine Verbindung zur Produktionsinstanz Ihres Projekts besteht:
- Öffnen Sie das Menü Produkt > Schema > Schema bearbeiten….
- Entfernen Sie im Bereich Ausführen das Häkchen beim Startargument
-useEmulator YES
.