1. Panoramica
Questo codelab ti guida nella procedura di integrazione di Firebase Data Connect con un database Cloud SQL per creare un'app di recensioni di film per iOS utilizzando SwiftUI
Scoprirai come collegare la tua applicazione per iOS a un database Cloud SQL utilizzando Firebase Data Connect, in modo da sincronizzare senza problemi i dati per le recensioni dei film.
Al termine di questo codelab, avrai un'app per iOS funzionale che consente agli utenti di sfogliare i film e contrassegnarli come preferiti, il tutto supportato da un database Cloud SQL che sfrutta la potenza di Firebase Data Connect.
Obiettivi didattici
Questo codelab ti insegnerà a:
- Configura Firebase Data Connect utilizzando la suite Firebase Emulator per tempi di risposta rapidi.
- Progetta uno schema di database utilizzando Data Connect e GraphQL.
- Crea un SDK Swift sicuro per i tipi dallo schema del database e aggiungilo a un'applicazione Swift.
- Implementa l'autenticazione utente e integrala con Firebase Data Connect per proteggere i dati dei tuoi utenti.
- Recupera, aggiorna, elimina e gestisci i dati in Cloud SQL utilizzando query e mutazioni basate su GraphQL.
- (Facoltativo) Esegui il deployment di un servizio Data Connect in produzione.
Prerequisiti
- La versione più recente di Xcode
- Il codice di esempio del codelab. Scaricherai il codice di esempio in uno dei primi passaggi del codelab.
2. Configura il progetto di esempio
Crea un progetto Firebase
- Accedi alla console Firebase con il tuo Account Google.
- Nella Console Firebase, fai clic su Crea un progetto Firebase.
- Inserisci un nome per il progetto Firebase (ad esempio "Friendly Flix") e fai clic su Continua.
- Potrebbe esserti chiesto di attivare l'assistenza AI per il tuo progetto Firebase. Ai fini di questo codelab, la tua selezione non ha importanza.
- È possibile che ti venga chiesto di attivare Google Analytics. Ai fini di questo codelab, la tua selezione non ha importanza.
- Dopo circa un minuto, il progetto Firebase sarà pronto. Fai clic su Continua.
Scarica il codice
Esegui il seguente comando per clonare il codice di esempio per questo codelab. Verrà creata una directory denominata codelab-dataconnect-ios
sulla tua macchina:
git clone https://github.com/peterfriese/codelab-dataconnect-ios`
Se non hai git sul tuo computer, puoi anche scaricare il codice direttamente da GitHub.
Aggiungi la configurazione di Firebase
L'SDK Firebase utilizza un file di configurazione per connettersi al tuo progetto Firebase. Sulle piattaforme Apple, questo file si chiama GoogleServices-Info.plist
. In questo passaggio, dovrai scaricare il file di configurazione e aggiungerlo al progetto Xcode.
- Nella console Firebase, seleziona Panoramica del progetto nel menu di navigazione a sinistra.
- Fai clic sul pulsante iOS+ per selezionare la piattaforma. Quando ti viene richiesto l'ID pacchetto Apple, utilizza
com.google.firebase.samples.FriendlyFlix
- Fai clic su Registra app e segui le istruzioni per scaricare il file
GoogleServices-Info.plist
. - Sposta il file scaricato nella directory
start/FriendlyFlix/app/FriendlyFlix/FriendlyFlix/
del codice che hai appena scaricato, sostituendo il fileGoogleServices-Info.plist
esistente. - Poi fai clic su Avanti un paio di volte per completare il progetto di configurazione nella console Firebase (non è necessario aggiungere l'SDK all'app, perché è già stato fatto nel progetto iniziale).
- Infine, fai clic su Vai alla console per completare la procedura di configurazione.
3. Configura Data Connect
Installazione
Installazione automatica
Esegui questo comando nella directory codelab-dataconnect-ios/FriendlyFlix
:
curl -sL https://firebase.tools/dataconnect | bash
Questo script tenta di configurare l'ambiente di sviluppo e di avviare un IDE basato su browser. Questo IDE fornisce strumenti, inclusa un'estensione VS Code precompilata, per aiutarti a gestire lo schema e a definire query e mutazioni da utilizzare nella tua applicazione, nonché a generare SDK fortemente tipizzati.
Dopo aver eseguito lo script, VS Code dovrebbe aprirsi automaticamente.
Dopo averlo fatto una volta, puoi avviare VS Code eseguendolo nella directory locale:
code .
Installazione manuale
- Installa Visual Studio Code
- Installa Node.js
- In VS Code, apri la directory
codelab-dataconnect-ios/FriendlyFlix
. - Installa l'estensione Firebase Data Connect dal Visual Studio Marketplace.
Inizializza Data Connect nel progetto
Nel riquadro a sinistra, fai clic sull'icona di Firebase per aprire l'interfaccia utente dell'estensione VS Code di Data Connect
- Fai clic sul pulsante Accedi con Google. Si aprirà una finestra del browser; segui le istruzioni per accedere all'estensione con il tuo Account Google.
- Fai clic sul pulsante Collega un progetto Firebase e seleziona il progetto che hai creato in precedenza nella console.
- Fai clic sul pulsante Esegui firebase init e segui i passaggi nel terminale integrato.
Configura la generazione dell'SDK
Dopo aver fatto clic sul pulsante Esegui firebase init, l'estensione Firebase Data Connect dovrebbe inizializzare una directory dataconnect
.
In VS Code, apri il file dataconnect/connector/connector.yaml
e troverai la configurazione predefinita.
Aggiorna la configurazione e utilizza le seguenti impostazioni per assicurarti che il codice generato funzioni con questo codelab. In particolare, assicurati che connectorId
sia impostato su friendly-flix
e il pacchetto Swift su FriendlyFlixSDK
.
connectorId: "friendly-flix"
generate:
swiftSdk:
outputDir: "../../app"
package: "FriendlyFlixSDK"
observablePublisher: observableMacro
Ecco il significato di queste impostazioni:
connectorId
: un nome univoco per questo connettore.outputDir
: percorso in cui verrà archiviato l'SDK Data Connect generato. Questo percorso è relativo alla directory contenente il fileconnector.yaml
.package
: il nome del pacchetto da utilizzare per il pacchetto Swift generato.
Dopo aver salvato questo file, Firebase Data Connect genererà un pacchetto Swift denominato FriendlyFlixSDK
e lo posizionerà accanto alla cartella del progetto FriendlyFlix
.
Avvia gli emulatori Firebase
In VS Code, passa alla visualizzazione Firebase e poi fai clic sul pulsante Avvia emulatori.
Verrà avviato Firebase Emulator nel terminale integrato. L'output dovrebbe essere simile al seguente:
npx -y firebase-tools@latest emulators:start --project <your-project-id>
Aggiungi il pacchetto generato all'app Swift
- Apri
FriendlyFlix/app/FriendlyFlix/FriendlyFlix.xcodeproj
in Xcode - Seleziona File > Aggiungi dipendenze del pacchetto….
- Fai clic su Aggiungi locale…, quindi aggiungi il pacchetto
FriendlyFlixSDK
dalla cartellaFriendlyFlix/app
- Attendi che Xcode risolva le dipendenze del pacchetto.
- Nella finestra di dialogo Scegli i prodotti del pacchetto per FriendlyFlixSDK, seleziona
FriendlyFlix
come target e fai clic su Aggiungi pacchetto.
Configura l'app per iOS in modo che utilizzi l'emulatore locale
- Apri
FriendlyFlixApp.swift
. Puoi premere CMD + Maiusc + O per aprire la finestra di dialogo Apri rapida, quindi digitare "FriendlyFlixApp" per trovare rapidamente il file. - Importa Firebase, Firebase Auth, Firebase Data Connect e l'SDK generato per lo schema
- Nell'inizializzatore, configura Firebase.
- Assicurati che DataConnect e Firebase Auth utilizzino l'emulatore locale.
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()
}
...
}
- Seleziona un simulatore iOS nel menu a discesa Destinazione.
- Premi CMD+R (o fai clic sul pulsante Esegui) in Xcode per eseguire l'app su un simulatore.
4. Definisci lo schema e precompila il database
In questa sezione, definirai la struttura e le relazioni tra le entità chiave dell'applicazione di film in uno schema. Entità come Movie
, MovieMetaData
e altre vengono mappate alle tabelle di database, con relazioni stabilite utilizzando Firebase Data Connect e le direttive dello schema GraphQL.
Entità e relazioni principali
Il modello di dati di questa app di monitoraggio dei film è costituito da diverse entità che creerai nel corso di questo codelab. Dovrai prima creare le entità di base e, man mano che implementi sempre più funzionalità, dovrai aggiungere le entità richieste per queste funzionalità.
In questo passaggio, creerai i tipi Movie
e MovieMetadata
.
Film
Il tipo Movie
definisce la struttura principale di un'entità film, inclusi campi come title
, genre
, releaseYear
e rating
.
In VS Code, aggiungi la definizione di tipo Movie
a dataconnect/schema/schema.gql
:
type Movie @table {
id: UUID! @default(expr: "uuidV4()")
title: String!
imageUrl: String!
releaseYear: Int
genre: String
rating: Float
description: String
tags: [String]
}
MovieMetadata
Il tipo MovieMetadata
stabilisce una relazione uno a uno con il tipo Movie
. Sono inclusi dati aggiuntivi, come il regista del film.
Aggiungi la definizione della tabella MovieMetadata
al file dataconnect/schema/schema.gql
:
type MovieMetadata @table {
movie: Movie! @ref
director: String
}
Campi e valori predefiniti generati automaticamente
Lo schema utilizza espressioni come @default(expr: "uuidV4()")
per generare automaticamente ID e timestamp univoci. Ad esempio, il campo id
nel tipo Movie
viene compilato automaticamente con un UUID quando viene creato un nuovo record.
Inserire dati simulati per film e metadati dei film
Una volta definito lo schema, puoi precompilare il database con dati simulati per i test.
- In Finder, copia
finish/FriendlyFlix/dataconnect/moviedata_insert.gql
nella cartellastart/FriendlyFlix/dataconnect
. - In VS Code, apri
dataconnect/moviedata_insert.gql
. - Assicurati che gli emulatori nell'estensione Firebase Data Connect siano in esecuzione.
- Nella parte superiore del file dovresti vedere il pulsante Esegui (locale). Fai clic qui per inserire i dati simulati dei film nel database.
- Controlla il terminale Data Connect Execution per verificare che i dati siano stati aggiunti correttamente.
Una volta inseriti i dati, vai al passaggio successivo per scoprire come creare query in Data Connect.
5. Recuperare e visualizzare i film
In questa sezione, implementerai una funzionalità per visualizzare un elenco di film.
Innanzitutto, imparerai a creare una query che recupera tutti i film dalla tabella movies
. Firebase Data Connect genera codice per un SDK sicuro per i tipi che puoi utilizzare per eseguire la query e visualizzare i film recuperati nell'interfaccia utente della tua app.
Definisci la query ListMovies
Le query in Firebase Data Connect sono scritte in GraphQL, il che ti consente di specificare quali campi recuperare. In FriendlyFlix, le schermate che mostrano i film richiedono i seguenti campi: title
, description
, releaseYear
, rating
e imageUrl
. Inoltre, poiché si tratta di un'app SwiftUI, avrai bisogno di id
per l'identità della visualizzazione SwiftUI.
In VS Code, apri il file dataconnect/connector/queries.gql
e aggiungi la query ListMovies
:
query ListMovies @auth(level: PUBLIC) {
movies {
id
title
imageUrl
releaseYear
genre
rating
tags
description
}
}
Per testare la nuova query, fai clic sul pulsante Esegui (locale) per eseguirla nel database locale. L'elenco dei film del database dovrebbe essere visualizzato nella sezione Risultati del terminale di esecuzione di Data Connect.
Collega la query ListMovies alla schermata Home dell'app
Ora che hai testato la query nell'emulatore Data Connect, puoi chiamarla dall'interno della tua app.
Quando salvi queries.gql
, Firebase Data Connect genera il codice corrispondente alla query ListMovies
nel pacchetto FriendlyFlixSDK
.
In Xcode, apri Movie+DataConnect.swift
e aggiungi il seguente codice per eseguire la mappatura da ListMoviesQuery.Data.Movie
a Movie
:
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
}
}
Apri il file HomeScreen.swift
e aggiornalo utilizzando il seguente snippet di codice.
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) ?? []
}
...
}
La query |
Esegui l'app
In Xcode, fai clic sul pulsante Esegui per avviare l'app nel Simulatore iOS.
Una volta avviata l'app, dovresti vedere una schermata simile alla seguente:
Potresti notare che tutte le aree dell'app (sezione in primo piano, film più popolari e lista di titoli) mostrano lo stesso elenco. Questo perché utilizzi la stessa query per tutte le viste. Nelle sezioni successive, implementerai le query personalizzate. |
6. Mostrare l'eroe e i film più popolari
In questo passaggio, ti concentrerai sull'aggiornamento del modo in cui i film vengono visualizzati nella sezione hero, ovvero il carosello in evidenza nella parte superiore della schermata Home, e anche nella sezione dei film più popolari di seguito.
Al momento, la query ListMovies recupera tutti i film. Per ottimizzare la visualizzazione di queste sezioni, dovrai limitare il numero di film restituiti da ogni query. L'attuale implementazione della query ListMovies
non offre ancora il supporto integrato per la limitazione dei risultati. L'aggiunta del supporto per la limitazione e l'ordinamento è un'operazione che dovrai eseguire in questa sezione.
Migliorare la query ListMovies
Apri queries.gql
e aggiorna ListMovies
come segue per aggiungere il supporto per l'ordinamento e il limite:
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
}
}
In questo modo, potrai limitare il numero di film restituiti dalla query e ordinare l'insieme di risultati in base alla classificazione e all'anno di uscita.
Dopo aver salvato questo file, Firebase Data Connect genererà automaticamente il codice entro FriendlyFlixSDK
. Nel passaggio successivo, puoi aggiornare il codice in HomeScreen.swift
per utilizzare queste funzionalità aggiuntive.
Utilizzare la query avanzata nell'interfaccia utente
Torna a Xcode per apportare le modifiche necessarie a HomeScreen.swift
.
Innanzitutto, aggiorna heroMoviesRef
per recuperare i tre film usciti più di recente:
struct HomeScreen {
...
init() {
heroMoviesRef = connector.listMoviesQuery
.ref { optionalVars in
optionalVars.limit = 3
optionalVars.orderByReleaseYear = .DESC
}
}
}
A questo punto, imposta un altro riferimento di query per i film più popolari e imposta il filtro sui 5 film con il voto più alto:
struct HomeScreen {
...
let topMoviesRef: QueryRefObservation<ListMoviesQuery.Data, ListMoviesQuery.Variables>
init() {
heroMoviesRef = ...
topMoviesRef = connector.listMoviesQuery
.ref { optionalVars in
optionalVars.limit = 5
optionalVars.orderByRating = .DESC
}
}
}
Infine, aggiorna la proprietà calcolata che collega il risultato di questa query all'interfaccia utente:
extension HomeScreen {
...
private var topMovies: [Movie] {
topMoviesRef.data?.movies.map(Movie.init) ?? []
}
}
Guarda come funziona
Esegui di nuovo l'app per vedere i 3 film più recenti nella sezione Hero e i 5 film con la valutazione più alta nella sezione Film più popolari:
7. Mostrare i dettagli di film e attori
Ora l'utente può sfogliare i film. Quando tocchi la scheda di un film, vengono visualizzati alcuni dettagli, ma potresti aver notato che mancano alcuni dettagli.
Questo perché abbiamo recuperato solo i dettagli necessari per visualizzare la sezione dei film in primo piano e la sezione dei film più popolari: il titolo del film, una breve descrizione e l'URL dell'immagine.
Nella pagina dei dettagli del film, vogliamo mostrare ulteriori informazioni sul film. In questa sezione migliorerai l'app in modo che possa mostrare gli attori del film e eventuali recensioni nella pagina dei dettagli.
A questo scopo, dovrai fare un paio di cose:
- Migliorare lo schema per supportare gli attori e le recensioni dei film
- Scrivi query Firebase Data Connect per recuperare i dettagli di un determinato film
- Visualizzazione dei risultati nella schermata dei dettagli del film
Migliorare lo schema
In VS Code, apri dataconnect/schema/schema.gql
e aggiungi le definizioni dello schema per Actor
e MovieActor
.
## 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"
}
Aggiungere dati simulati per gli attori
Con lo schema aggiornato, ora puoi compilare il database con altri dati simulati per i test.
- In Finder, copia
finish/FriendlyFlix/dataconnect/moviededetails_insert.gql
nella cartellastart/FriendlyFlix/dataconnect
. - In VS Code, apri
dataconnect/moviededetails_insert.gql
. - Assicurati che gli emulatori nell'estensione Firebase Data Connect siano in esecuzione.
- Nella parte superiore del file dovresti vedere il pulsante Esegui (locale). Fai clic qui per inserire i dati simulati dei film nel database.
- Controlla il terminale di esecuzione di Data Connect per verificare che i dati siano stati aggiunti correttamente.
Una volta inseriti i dati, vai al passaggio successivo per definire la query per recuperare i dettagli del film.
Definisci la query GetMovieById
In VS Code, apri il file dataconnect/connector/queries.gql
e aggiungi la query GetMovieById
:
## 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
}
}
}
Collega la query GetMovieById a MovieDetailsView
In Xcode, apri il file MovieDetailsView.swift
e aggiorna la proprietà calcolata movieDetails
in modo che corrisponda al seguente codice:
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
}
}
Esegui l'app
In Xcode, fai clic sul pulsante Esegui per avviare l'app sul simulatore iOS.
Una volta avviata l'app, tocca una scheda del film per visualizzarne i dettagli. Dovrebbe avere il seguente aspetto:
8. Implementare l'autenticazione utente
Al momento, l'app presenta informazioni non personalizzate su film e attori. Nei passaggi successivi, implementerai funzionalità che associano i dati all'utente che ha eseguito l'accesso. Inizia consentendo agli utenti di aggiungere film alla loro lista di titoli personale.
Prima di poter implementare la funzionalità della lista di controllo, devi stabilire l'identità dell'utente. Per abilitare questa funzionalità, dovrai integrare Firebase Authentication, consentendo agli utenti di accedere all'app.
Potresti aver già notato il pulsante dell'avatar utente in alto a destra nella schermata Home. Se lo tocchi, viene visualizzata una schermata in cui gli utenti possono registrarsi o accedere utilizzando il proprio indirizzo email e la propria password.
Una volta che un utente ha eseguito l'accesso, la tua app dovrà memorizzare i suoi dati essenziali, in particolare il suo ID utente univoco e il nome utente scelto.
Attiva Firebase Authentication
Nella Console Firebase del tuo progetto, vai alla sezione Autenticazione e abilita Firebase Authentication. Poi, attiva il provider di autenticazione email/password.
Nella cartella del progetto locale, individua firebase.json
e aggiornalo come segue per attivare l'emulatore Firebase Authentication.
{
"emulators": {
"dataconnect": {
},
"auth": {
}
},
"dataconnect": {
"source": "dataconnect"
}
}
Dopodiché, devi interrompere e riavviare Firebase Emulator affinché la modifica venga applicata.
Implementare un gestore di autenticazione
Nella sezione seguente, implementerai la logica che collega l'autenticazione utente al tuo database. Ciò comporta la creazione di un gestore di autenticazione che ascolta gli accessi riusciti.
Una volta autenticato l'utente, questo gestore attiverà automaticamente la creazione del relativo account nel tuo database.
In Xcode, apri il file AuthenticationService.swift
e aggiungi il seguente codice:
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
}
}
Si tratta di un gestore di autenticazione generico che ti consente di utilizzare onSignUp
per registrare una chiusura che verrà chiamata quando l'utente avrà eseguito l'accesso.
All'interno di questa chiusura, puoi creare un nuovo account utente nel database. Tuttavia, prima di poterlo fare, devi creare una mutazione che ti consenta di creare o aggiornare nuovi utenti nel database.
Aggiungi un'entità Utente allo schema
Il tipo User
definisce un'entità utente. Gli utenti possono interagire con i film lasciando recensioni o aggiungendoli ai preferiti.
In VS Code, apri il file dataconnect/schema/schema.gql
e aggiungi la seguente definizione della tabella User
:
## 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)")
}
Definire una mutazione per l'inserimento o l'aggiornamento di un utente
In VS Code, apri il file dataconnect/connector/mutations.gql
e aggiungi la mutazione UpsertUser
:
mutation UpsertUser($username: String!) @auth(level: USER) {
user_upsert(
data: {
id_expr: "auth.uid"
username: $username
}
)
}
Creare un nuovo utente dopo aver eseguito l'accesso
In Xcode, apri FriendlyFlixApp.swift
e aggiungi il seguente codice all'inizializzatore:
@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 {
...
}
}
Questo codice utilizza upsertUserMutation
Firebase Data Connect generato per te per inserire un nuovo utente (o aggiornare un utente esistente con lo stesso ID) ogni volta che un utente si registra correttamente utilizzando Firebase Authentication.
Guarda come funziona
Per verificare che funzioni, registrati prima nell'app per iOS:
- Se non l'hai ancora fatto, interrompi e riavvia Firebase Emulator per assicurarti che Firebase Authentication Emulator sia in esecuzione.
- In Xcode, fai clic sul pulsante Esegui per avviare l'app sul simulatore iOS.
- Fai clic sull'icona dell'avatar nell'angolo in alto a destra dello schermo.
- Passa alla procedura Registrati e registrati all'app.
Quindi, esegui una query sul database per verificare che l'app abbia creato un nuovo account utente per l'utente:
- In VS Code, apri
dataconnect/schema/schema.gql
e fai clic su Leggi dati sull'entitàUser
. - Verrà creato un nuovo file di query denominato
User_read.gql
- Fai clic su Esegui locale per visualizzare tutti gli utenti nella tabella degli utenti.
- Nel riquadro Esecuzione di Data Connect, dovresti ora vedere un account per l'utente con cui hai appena eseguito la registrazione
9. Gestire i film preferiti
In questa sezione del codelab, implementerai le interazioni degli utenti nell'app di recensione dei film, in particolare consentendo agli utenti di gestire i loro film preferiti. I film contrassegnati come preferiti verranno visualizzati nella sezione della lista di titoli dell'app.
Migliorare lo schema per supportare i preferiti
Il tipo FavoriteMovie
è una tabella di join che gestisce le relazioni many-to-many tra gli utenti e i loro film preferiti. Ogni tabella collega un User
a un Movie
.
Copia e incolla lo snippet di codice nel file dataconnect/schema/schema.gql
:
type FavoriteMovie
@table(name: "FavoriteMovies", singular: "favorite_movie", plural: "favorite_movies", key: ["user", "movie"]) {
## @ref is implicit
user: User!
movie: Movie!
}
Definire le mutazioni per l'aggiunta e la rimozione dei preferiti
Prima che l'app possa mostrare i film preferiti dell'utente, l'utente deve indicare quali sono i suoi preferiti. Per farlo, devi prima aggiungere due mutazioni per contrassegnare un film come uno dei preferiti dell'utente o rimuoverlo di nuovo dai preferiti.
- In VS Code, apri
mutations.gql
indataconnect/connector/mutations.gql
- Aggiungi le seguenti mutazioni per gestire l'aggiunta di film ai preferiti:
## 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 })
}
Collega le mutazioni all'interfaccia utente dell'app
Gli utenti possono contrassegnare un film come preferito facendo clic sull'icona a forma di cuore nella schermata dei dettagli del film.
Per collegare le mutazioni che hai appena creato all'interfaccia utente dell'app, apporta le seguenti modifiche in MovieCardView
:
- Importa il
FriendlyFlixSDK
e configura il connettore
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
...
}
- Implementa il metodo
toggleFavourite
. Verrà chiamato ogni volta che l'utente tocca l'icona a forma di cuore inMovieCardView
:
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)
}
}
}
}
In questo modo, lo stato del film preferito corrente nel database verrà aggiornato. Un ultimo passaggio mancante è assicurarsi che lo stato dell'interfaccia utente venga visualizzato di conseguenza.
Definire una query per capire se un film è contrassegnato come preferito
- In VS Code, apri
queries.gql
indataconnect/connector
. - Aggiungi la seguente query per verificare se un film è contrassegnato come preferito:
query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) {
movieId
}
}
- In Xcode, crea un'istanza di un riferimento alla query
GetIfFavoritedMovie
e implementa la proprietà calcolata che determina se il film mostrato in questoGetIfFavoritedMovie
è contrassegnato come preferito per l'utente corrente.MovieCardView
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
}
...
}
- Aggiorna il codice in
toggleFavourite
per eseguire la query ogni volta che l'utente tocca il pulsante. In questo modo, la proprietà calcolataisFavourite
restituisce sempre il valore corretto.
private func toggleFavourite() {
Task {
if isFavourite {
...
}
let _ = try await isFavouriteRef.execute()
}
}
Recuperare i film preferiti
Come ultimo passaggio per questa funzionalità, implementerai il recupero dei film preferiti dell'utente in modo che possa vederli nella sua lista di titoli.
- In VS Code, apri
queries.gql
indataconnect/connector/queries.gql
e incolla la seguente query:
## 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
}
}
}
}
L'elenco dei film preferiti dell'utente viene visualizzato su LibraryScreen
. Questa schermata deve mostrare i dati solo se l'utente ha eseguito l'accesso, quindi dovrai prima collegare lo stato di autenticazione della schermata a AuthenticationService
dell'app.
- Aggiungi il codice per mappare da
FavoriteMovieFavoriteMovies
aMovie
aMovie+DataConnect.swift
:
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
}
}
- In Xcode, apri
LibraryScreen
, quindi aggiornaisSignedIn
come segue:
struct LibraryScreen: View {
...
private var isSignedIn: Bool {
authenticationService.user != nil
}
}
- Importa quindi Firebase Data Connect e FriendlyFlixSDK e ottieni un riferimento alla query
GetUserFavoriteMovies
:
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) ?? []
}
...
}
- Assicurati che la query
watchListRef
venga eseguita quando viene visualizzata la vista:
extension LibraryScreen: View {
var body: some View {
...
MovieListSection(namespace: namespace, title: "Watch List", movies: watchList)
.onAppear {
Task {
try await watchListRef.execute()
}
...
Guarda come funziona
Ora puoi eseguire l'app e provare la funzionalità Preferiti che hai appena implementato. Ecco un paio di aspetti da tenere presente:
- Assicurati che l'emulatore Firebase sia in esecuzione
- Assicurati di aver aggiunto dati simulati per i film e i relativi dettagli
- Assicurati di aver eseguito la registrazione come utente
- In Xcode, fai clic sul pulsante Esegui per avviare l'app sul simulatore iOS.
- Una volta avviata l'app, tocca una scheda del film per visualizzarne i dettagli.
- Tocca l'icona a forma di cuore per contrassegnare il film come preferito. Il cuore dovrebbe diventare solido.
- Ripeti l'operazione per un paio di film.
- Vai alla scheda Raccolta. Dovresti vedere un elenco di tutti i film che hai contrassegnato come preferiti.
10. Complimenti
Complimenti, hai aggiunto Firebase Data Connect a un'app per iOS. Ora conosci i passaggi chiave necessari per configurare Data Connect, creare query e mutazioni e gestire l'autenticazione utente.
(Facoltativo) Esegui il deployment in produzione
Finora questa app ha utilizzato solo gli emulatori Firebase. Se vuoi scoprire come eseguire il deployment di questa app in un progetto Firebase reale, vai al passaggio successivo.
11. (Facoltativo) Esegui il deployment dell'app
Finora questa app è stata completamente locale, tutti i dati sono contenuti in Firebase Emulator Suite. In questa sezione imparerai a configurare il progetto Firebase in modo che l'app funzioni in produzione.
Attiva Firebase Authentication
- Nella console Firebase, vai alla sezione Autenticazione e fai clic su Inizia.
- Vai alla scheda Metodo di accesso .
- Seleziona l'opzione Email/Password dalla sezione dei provider nativi.
- Attiva il provider email/password e poi fai clic su Salva.
Attiva Firebase Data Connect
Importante: se è la prima volta che esegui il deployment di uno schema nel progetto, questa procedura creerà un'istanza PostgreSQL Cloud SQL, il che può richiedere circa 15 minuti. Non potrai eseguire il deployment finché l'istanza Cloud SQL non sarà pronta e integrata con Firebase Data Connect.
1. Nell'interfaccia utente dell'estensione Firebase Data Connect per VS Code, fai clic su Esegui il deployment in produzione. 2. Potresti dover esaminare le modifiche allo schema e approvare modifiche potenzialmente dannose. Ti verrà chiesto di: - esaminare le modifiche allo schema utilizzando firebase dataconnect:sql:diff
- quando le modifiche ti soddisfano, applicarle utilizzando il flusso avviato da firebase dataconnect:sql:migrate
L'istanza Cloud SQL per PostgreSQL verrà aggiornata con lo schema e i dati di cui è stato eseguito il deployment finale. Puoi monitorare lo stato nella Console Firebase.
Ora puoi fare clic su Esegui (produzione) nel riquadro Firebase Data Connect, proprio come hai fatto con gli emulatori locali, per aggiungere dati all'ambiente di produzione.
Prima di eseguire di nuovo l'app per iOS, assicurati che si connetta all'istanza di produzione del progetto:
- Apri il menu Product > Scheme > Edit Scheme… (Prodotto > Schema > Modifica schema…).
- Nella sezione Esegui, deseleziona l'argomento di lancio
-useEmulator YES
.