1. Przegląd
Ten przewodnik przeprowadzi Cię przez proces integrowania Firebase Data Connect z bazą danych Cloud SQL w celu utworzenia aplikacji do oceniania filmów na iOS przy użyciu SwiftUI.
Dowiesz się, jak połączyć aplikację na iOS z bazą danych Cloud SQL za pomocą Firebase Data Connect, co umożliwi płynną synchronizację danych dotyczących recenzji filmów.
Po ukończeniu tego laboratorium uzyskasz działającą aplikację na iOS, która umożliwia użytkownikom przeglądanie filmów i oznaczanie ich jako ulubionych. Wszystko to będzie oparte na bazie danych Cloud SQL z wykorzystaniem możliwości Firebase Data Connect.
Czego się nauczysz
Z tego modułu dowiesz się, jak:
- Skonfiguruj Firebase Data Connect, korzystając z pakietu emulatorów Firebase, aby szybko uzyskać wyniki.
- Zaprojektuj schemat bazy danych za pomocą Data Connect i GraphQL.
- Utwórz bezpieczny pod względem typów pakiet SDK w Swift na podstawie schematu bazy danych i dodaj go do aplikacji w Swift.
- Wdróż uwierzytelnianie użytkowników i zintegruj je z Firebase Data Connect, aby zabezpieczyć dane użytkowników.
- Pobieraj, aktualizuj, usuwaj dane w Cloud SQL i zarządzaj nimi za pomocą zapytań i mutacji obsługiwanych przez GraphQL.
- (Opcjonalnie) Wdróż usługę Data Connect w środowisku produkcyjnym.
Wymagania wstępne
- najnowsza wersja Xcode,
- Przykładowy kod z warsztatów. Przykładowy kod pobierzesz w jednym z pierwszych kroków tego laboratorium.
2. Konfigurowanie przykładowego projektu
Tworzenie projektu Firebase
- Zaloguj się w konsoli Firebase, korzystając ze swojego konta Google.
- Kliknij przycisk, aby utworzyć nowy projekt, a potem wpisz jego nazwę (np.
Friendly Flix
).
- Kliknij Dalej.
- Po wyświetleniu monitu przeczytaj i zaakceptuj warunki usługi Firebase, a potem kliknij Dalej.
- (Opcjonalnie) Włącz w konsoli Firebase pomoc AI (nazywaną „Gemini w Firebase”).
- W tym samouczku nie potrzebujesz Google Analytics, więc wyłącz opcję Google Analytics.
- Kliknij Utwórz projekt, poczekaj, aż projekt zostanie udostępniony, a następnie kliknij Dalej.
Pobieranie kodu
Aby skopiować przykładowy kod do tego laboratorium, uruchom to polecenie. Spowoduje to utworzenie na Twoim komputerze katalogu o nazwie codelab-dataconnect-ios
:
git clone https://github.com/FirebaseExtended/codelab-dataconnect-ios`
Jeśli nie masz na komputerze narzędzia git, możesz też pobrać kod bezpośrednio z GitHub.
Dodawanie konfiguracji Firebase
Pakiet SDK Firebase używa pliku konfiguracyjnego do łączenia się z projektem Firebase. Na platformach Apple ten plik nazywa się GoogleServices-Info.plist
. W tym kroku pobierzesz plik konfiguracyjny i dodasz go do projektu Xcode.
- W konsoli Firebase w menu po lewej stronie wybierz Przegląd projektu.
- Aby wybrać platformę, kliknij przycisk iOS+. Gdy pojawi się prośba o podanie identyfikatora pakietu Apple, użyj
com.google.firebase.samples.FriendlyFlix
- Kliknij Zarejestruj aplikację i wykonaj instrukcje, aby pobrać plik
GoogleServices-Info.plist
. - Przenieś pobrany plik do katalogu
start/FriendlyFlix/app/FriendlyFlix/FriendlyFlix/
w pobranych właśnie plikach kodu, zastępując istniejący plikGoogleServices-Info.plist
. - Następnie kilka razy kliknij Dalej, aby dokończyć konfigurację projektu w konsoli Firebase (nie musisz dodawać pakietu SDK do aplikacji, ponieważ zostało to już zrobione w projekcie początkowym).
- Na koniec kliknij Przejdź do konsoli, aby zakończyć proces konfiguracji.
3. Konfigurowanie Data Connect
Instalacja
Automatyczna instalacja
W katalogu codelab-dataconnect-ios/FriendlyFlix
uruchom to polecenie:
curl -sL https://firebase.tools/dataconnect | bash
Ten skrypt próbuje skonfigurować środowisko programistyczne i uruchomić środowisko IDE w przeglądarce. To środowisko IDE udostępnia narzędzia, w tym wstępnie dołączone rozszerzenie VS Code, które pomagają zarządzać schematem, definiować zapytania i mutacje do użycia w aplikacji oraz generować pakiety SDK o silnym typowaniu.
Po uruchomieniu skryptu VS Code powinien otworzyć się automatycznie.
Gdy to zrobisz, możesz uruchomić VS Code, wykonując to polecenie w lokalnym katalogu:
code .
Instalacja ręczna
- Zainstaluj Visual Studio Code.
- Zainstaluj Node.js.
- W VS Code otwórz katalog
codelab-dataconnect-ios/FriendlyFlix
. - Zainstaluj rozszerzenie Firebase Data Connect z Visual Studio Code Marketplace.
Inicjowanie Data Connect w projekcie
W panelu po lewej stronie kliknij ikonę Firebase, aby otworzyć interfejs rozszerzenia Data Connect VS Code.
- Kliknij przycisk Zaloguj się przez Google. Otworzy się okno przeglądarki. Postępuj zgodnie z instrukcjami, aby zalogować się w rozszerzeniu za pomocą konta Google.
- Kliknij przycisk Połącz z projektem Firebase i wybierz projekt utworzony wcześniej w konsoli.
- Kliknij przycisk Run firebase init (Uruchom firebase init) i postępuj zgodnie z instrukcjami w zintegrowanym terminalu.
Konfigurowanie generowania pakietu SDK
Po kliknięciu przycisku Run firebase init (Uruchom firebase init) rozszerzenie Firebase Data Connect powinno zainicjować katalog dataconnect
.
W VS Code otwórz plik dataconnect/connector/connector.yaml
, w którym znajdziesz domyślną konfigurację.
Zaktualizuj konfigurację i użyj tych ustawień, aby wygenerowany kod działał w tym ćwiczeniu z programowania. Sprawdź, czy connectorId
jest ustawiony na friendly-flix
, a pakiet Swift na FriendlyFlixSDK
.
connectorId: "friendly-flix"
generate:
swiftSdk:
outputDir: "../../app"
package: "FriendlyFlixSDK"
observablePublisher: observableMacro
Znaczenie tych ustawień jest następujące:
connectorId
– unikalna nazwa tego oprogramowania sprzęgającego.outputDir
– ścieżka, w której będzie przechowywany wygenerowany pakiet SDK Data Connect. Ścieżka jest podawana względem katalogu zawierającego plikconnector.yaml
.package
– nazwa pakietu, która ma być używana w wygenerowanym pakiecie Swift.
Po zapisaniu tego pliku usługa Firebase Data Connect wygeneruje pakiet Swift o nazwie FriendlyFlixSDK
i umieści go obok folderu projektu FriendlyFlix
.
Uruchamianie emulatorów Firebase
W VS Code przełącz się na widok Firebase, a następnie kliknij przycisk Uruchom emulatory.
Spowoduje to uruchomienie emulatora Firebase w zintegrowanym terminalu. Dane wyjściowe powinny wyglądać tak:
npx -y firebase-tools@latest emulators:start --project <your-project-id>
Dodawanie wygenerowanego pakietu do aplikacji Swift
- Otwórz
FriendlyFlix/app/FriendlyFlix/FriendlyFlix.xcodeproj
w Xcode - Wybierz Plik > Dodaj zależności pakietu...
- Kliknij Dodaj lokalny..., a następnie dodaj pakiet
FriendlyFlixSDK
z folderuFriendlyFlix/app
. - Poczekaj, aż Xcode przetworzy zależności pakietu.
- W oknie Choose Package Products for FriendlyFlixSDK (Wybierz produkty pakietowe dla FriendlyFlixSDK) wybierz
FriendlyFlix
jako miejsce docelowe i kliknij Add Package (Dodaj pakiet).
Konfigurowanie aplikacji na iOS do korzystania z lokalnego emulatora
- Otwórz pokój
FriendlyFlixApp.swift
. (Aby otworzyć okno Szybkie otwieranie, możesz nacisnąć CMD + Shift + O, a następnie wpisać „FriendlyFlixApp”, aby szybko znaleźć plik). - Zaimportuj Firebase, Firebase Auth, Firebase Data Connect i wygenerowany pakiet SDK dla schematu.
- W inicjatorze skonfiguruj Firebase.
- Upewnij się, że DataConnect i Uwierzytelnianie Firebase korzystają z lokalnego emulatora.
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()
}
...
}
- Wybierz symulator iOS w menu Miejsce docelowe.
- Naciśnij CMD+R (lub kliknij przycisk Uruchom) w Xcode, aby uruchomić aplikację w symulatorze.
4. Zdefiniuj schemat i wstępnie wypełnij bazę danych
W tej sekcji zdefiniujesz strukturę i relacje między kluczowymi elementami aplikacji do obsługi filmów w schemacie. Jednostki takie jak Movie
, MovieMetaData
i inne są mapowane na tabele bazy danych, a relacje są tworzone za pomocą usługi Firebase Data Connect i dyrektyw schematu GraphQL.
Podstawowe encje i relacje
Model danych tej aplikacji do śledzenia filmów składa się z kilku elementów, które utworzysz w trakcie tego ćwiczenia. Najpierw utworzysz podstawowe encje, a potem, w miarę wdrażania kolejnych funkcji, będziesz dodawać encje wymagane do ich działania.
W tym kroku utworzysz typy Movie
i MovieMetadata
.
Film
Typ Movie
określa główną strukturę elementu filmu, w tym pola takie jak title
, genre
, releaseYear
i rating
.
W VS Code dodaj definicję typu Movie
do pliku 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
Typ MovieMetadata
tworzy relację jeden do jednego z typem Movie
. Zawiera dodatkowe dane, np. imię i nazwisko reżysera filmu.
Dodaj definicję tabeli MovieMetadata
do pliku dataconnect/schema/schema.gql
:
type MovieMetadata @table {
movie: Movie! @ref
director: String
}
Pola i wartości domyślne generowane automatycznie
Schemat używa wyrażeń takich jak @default(expr: "uuidV4()")
do automatycznego generowania unikalnych identyfikatorów i sygnatur czasowych. Na przykład pole id
w typie Movie
jest automatycznie wypełniane identyfikatorem UUID podczas tworzenia nowego rekordu.
Wstawianie danych testowych dotyczących filmów i metadanych filmów
Po zdefiniowaniu schematu możesz wstępnie wypełnić bazę danych danymi testowymi.
- W Finderze skopiuj
finish/FriendlyFlix/dataconnect/moviedata_insert.gql
do folderustart/FriendlyFlix/dataconnect
. - W VS Code otwórz
dataconnect/moviedata_insert.gql
. - Sprawdź, czy emulatory w rozszerzeniu Firebase Data Connect działają.
- U góry pliku powinien być widoczny przycisk Uruchom (lokalnie). Kliknij tę opcję, aby wstawić do bazy danych przykładowe dane filmów.
- Sprawdź terminal Data Connect Execution, aby potwierdzić, że dane zostały dodane.
Gdy dane będą już dostępne, przejdź do następnego kroku, aby dowiedzieć się, jak tworzyć zapytania w Data Connect.
5. Pobieranie i wyświetlanie filmów
W tej sekcji zaimplementujesz funkcję wyświetlania listy filmów.
Najpierw dowiesz się, jak utworzyć zapytanie, które pobiera wszystkie filmy z tabeli movies
. Firebase Data Connect generuje kod bezpiecznego pod względem typów pakietu SDK, którego możesz użyć do wykonania zapytania i wyświetlenia pobranych filmów w interfejsie aplikacji.
Zdefiniuj zapytanie ListMovies
Zapytania w usłudze Firebase Data Connect są pisane w języku GraphQL, co pozwala określać, które pola mają być pobierane. W FriendlyFlix ekrany, na których wyświetlane są filmy, wymagają tych pól: title
, description
, releaseYear
, rating
i imageUrl
. Dodatkowo, ponieważ jest to aplikacja SwiftUI, będziesz potrzebować id
, aby pomóc w identyfikacji widoku SwiftUI.
W VS Code otwórz plik dataconnect/connector/queries.gql
i dodaj zapytanie ListMovies
:
query ListMovies @auth(level: PUBLIC) {
movies {
id
title
imageUrl
releaseYear
genre
rating
tags
description
}
}
Aby przetestować nowe zapytanie, kliknij przycisk Uruchom (lokalnie), aby wykonać zapytanie w lokalnej bazie danych. Lista filmów z bazy danych powinna być wyświetlana w sekcji Wyniki terminala wykonania Data Connect.
Połącz zapytanie ListMovies z ekranem głównym aplikacji.
Po przetestowaniu zapytania w emulatorze Data Connect możesz wywołać je z poziomu aplikacji.
Gdy zapiszesz queries.gql
, Firebase Data Connect wygeneruje kod odpowiadający zapytaniu ListMovies
w pakiecie FriendlyFlixSDK
.
W Xcode otwórz plik Movie+DataConnect.swift
i dodaj ten kod, aby mapować ListMoviesQuery.Data.Movie
na 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
}
}
Otwórz plik HomeScreen.swift
i zaktualizuj go, używając tego fragmentu kodu.
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) ?? []
}
...
}
Zapytanie |
Uruchamianie aplikacji
W Xcode kliknij przycisk Uruchom, aby uruchomić aplikację w symulatorze iOS.
Po uruchomieniu aplikacji powinien pojawić się ekran podobny do tego:
Możesz zauważyć, że we wszystkich obszarach aplikacji (sekcja główna, najpopularniejsze filmy i lista do obejrzenia) wyświetla się ta sama lista. Dzieje się tak, ponieważ we wszystkich tych widokach używasz tego samego zapytania. W kolejnych sekcjach zaimplementujesz niestandardowe zapytania. |
6. Wyświetlanie banera i najpopularniejszych filmów
W tym kroku skupisz się na zaktualizowaniu sposobu wyświetlania filmów w sekcji głównej – czyli w widocznym karuzelowym banerze u góry ekranu głównego – oraz w sekcji z najpopularniejszymi filmami poniżej.
Obecnie zapytanie ListMovies pobiera wszystkie filmy. Aby zoptymalizować wyświetlanie tych sekcji, ograniczysz liczbę filmów zwracanych przez każde zapytanie. Obecna implementacja zapytania ListMovies
nie oferuje jeszcze wbudowanej obsługi ograniczania wyników. W tej sekcji dodasz obsługę ograniczania i sortowania.
Ulepszanie zapytania ListMovies
Otwórz queries.gql
i zaktualizuj ListMovies
w ten sposób, aby dodać obsługę sortowania i ograniczania:
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
}
}
Pozwoli to ograniczyć liczbę filmów zwracanych przez zapytanie i uporządkować zbiór wyników według oceny i roku premiery.
Po zapisaniu tego pliku Firebase Data Connect automatycznie wygeneruje ponownie kod w FriendlyFlixSDK
. W następnym kroku możesz zaktualizować kod w HomeScreen.swift
, aby korzystać z tych dodatkowych funkcji.
Używanie rozszerzonego zapytania w interfejsie
Wróć do Xcode, aby wprowadzić wymagane zmiany w HomeScreen.swift
.
Najpierw zaktualizuj heroMoviesRef
, aby pobrać 3 ostatnio wydane filmy:
struct HomeScreen {
...
init() {
heroMoviesRef = connector.listMoviesQuery
.ref { optionalVars in
optionalVars.limit = 3
optionalVars.orderByReleaseYear = .DESC
}
}
}
Następnie skonfiguruj kolejne odwołanie do zapytania dotyczące najlepszych filmów i ustaw filtr na 5 najwyżej ocenianych filmów:
struct HomeScreen {
...
let topMoviesRef: QueryRefObservation<ListMoviesQuery.Data, ListMoviesQuery.Variables>
init() {
heroMoviesRef = ...
topMoviesRef = connector.listMoviesQuery
.ref { optionalVars in
optionalVars.limit = 5
optionalVars.orderByRating = .DESC
}
}
}
Na koniec zaktualizuj właściwość obliczoną, która łączy wynik tego zapytania z interfejsem:
extension HomeScreen {
...
private var topMovies: [Movie] {
topMoviesRef.data?.movies.map(Movie.init) ?? []
}
}
Jak to działa w praktyce
Uruchom ponownie aplikację, aby zobaczyć 3 najnowsze filmy w sekcji głównej i 5 najwyżej ocenianych filmów w sekcji najlepszych filmów:
7. Wyświetlanie szczegółów filmu i aktora
Użytkownik może teraz przeglądać filmy. Po kliknięciu karty filmu wyświetlą się szczegóły, ale możesz zauważyć, że brakuje w nich pewnych informacji.
Dzieje się tak, ponieważ pobraliśmy tylko tyle szczegółów o każdym filmie, ile było nam potrzebne do wyrenderowania sekcji głównej filmu i sekcji z najpopularniejszymi filmami: tytuł filmu, krótki opis i adres URL obrazu.
Na stronie z informacjami o filmie chcemy wyświetlać więcej informacji o tym filmie. W tej sekcji ulepszysz aplikację, aby na stronie szczegółów wyświetlała aktorów filmu i wszystkie recenzje.
W tym celu musisz wykonać kilka czynności:
- Rozszerzanie schematu o obsługę aktorów filmowych i recenzji
- Tworzenie zapytań Firebase Data Connect w celu pobierania szczegółowych informacji o danym filmie
- Wyświetlanie wyników na ekranie szczegółów filmu
Ulepszanie schematu
W VS Code otwórz dataconnect/schema/schema.gql
i dodaj definicje schematu dla Actor
i 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"
}
Dodawanie danych testowych dla aktorów
Po zaktualizowaniu schematu możesz wypełnić bazę danych większą ilością danych testowych.
- W Finderze skopiuj
finish/FriendlyFlix/dataconnect/moviededetails_insert.gql
do folderustart/FriendlyFlix/dataconnect
. - W VS Code otwórz
dataconnect/moviededetails_insert.gql
. - Sprawdź, czy emulatory w rozszerzeniu Firebase Data Connect działają.
- U góry pliku powinien być widoczny przycisk Uruchom (lokalnie). Kliknij tę opcję, aby wstawić do bazy danych przykładowe dane filmów.
- Sprawdź terminal Data Connect Execution, aby potwierdzić, że dane zostały dodane.
Gdy dane będą już na miejscu, przejdź do następnego kroku, aby zdefiniować zapytanie służące do pobierania szczegółowych informacji o filmie.
Zdefiniuj zapytanie GetMovieById
W VS Code otwórz plik dataconnect/connector/queries.gql
i dodaj zapytanie 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
}
}
}
Połącz zapytanie GetMovieById z widokiem MovieDetailsView
W Xcode otwórz plik MovieDetailsView.swift
i zaktualizuj właściwość obliczaną movieDetails
, aby pasowała do tego kodu:
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
}
}
Uruchamianie aplikacji
W Xcode kliknij przycisk Uruchom, aby uruchomić aplikację w symulatorze iOS.
Po uruchomieniu aplikacji kliknij kartę filmu, aby wyświetlić jego szczegóły. Powinien on wyglądać podobnie do tego:
8. Wdrażanie uwierzytelniania użytkowników
Obecnie aplikacja wyświetla niespersonalizowane informacje o filmach i aktorach. W kolejnych krokach wdrożysz funkcje, które powiążą dane z zalogowanym użytkownikiem. Zacznij od umożliwienia użytkownikom dodawania filmów do osobistej listy Do obejrzenia.
Zanim wdrożysz funkcję listy obserwacyjnej, musisz najpierw ustalić tożsamość użytkownika. Aby to zrobić, zintegruj uwierzytelnianie Firebase, które umożliwi użytkownikom logowanie się w aplikacji.
Przycisk z awatarem użytkownika znajduje się w prawym górnym rogu ekranu głównego. Po kliknięciu tego przycisku otworzy się ekran, na którym użytkownicy mogą się zarejestrować lub zalogować przy użyciu adresu e-mail i hasła.
Gdy użytkownik zaloguje się, aplikacja musi zapisać jego podstawowe dane, przede wszystkim unikalny identyfikator użytkownika i wybraną nazwę użytkownika.
Włączanie Uwierzytelniania Firebase
W konsoli Firebase w projekcie otwórz sekcję Uwierzytelnianie i włącz Uwierzytelnianie Firebase. Następnie włącz dostawcę uwierzytelniania przy użyciu adresu e-mail i hasła.
W lokalnym folderze projektu znajdź plik firebase.json
i zaktualizuj go w ten sposób, aby włączyć emulator uwierzytelniania Firebase.
{
"emulators": {
"dataconnect": {
},
"auth": {
}
},
"dataconnect": {
"source": "dataconnect"
}
}
Następnie musisz zatrzymać i ponownie uruchomić emulator Firebase, aby zmiana została zastosowana.
Implementowanie modułu obsługi uwierzytelniania
W następnej sekcji zaimplementujesz logikę, która łączy uwierzytelnianie użytkowników z bazą danych. Wymaga to utworzenia modułu obsługi uwierzytelniania, który nasłuchuje udanych logowań.
Po uwierzytelnieniu użytkownika ten moduł obsługi automatycznie spowoduje utworzenie odpowiedniego konta w Twojej bazie danych.
W Xcode otwórz plik AuthenticationService.swift
i dodaj ten kod:
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
}
}
Jest to ogólny moduł obsługi uwierzytelniania, który umożliwia użycie onSignUp
do zarejestrowania zamknięcia, które zostanie wywołane po zalogowaniu się użytkownika.
W tym zamknięciu możesz utworzyć nowe konto użytkownika w bazie danych. Zanim to zrobisz, musisz utworzyć mutację, która umożliwi Ci tworzenie lub aktualizowanie nowych użytkowników w bazie danych.
Dodawanie do schematu encji User
Typ User
definiuje element użytkownika. Użytkownicy mogą wchodzić w interakcje z filmami, dodając opinie lub oznaczając je jako ulubione.
W VS Code otwórz plik dataconnect/schema/schema.gql
i dodaj tę definicję tabeli 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)")
}
Zdefiniuj mutację wstawiającą lub aktualizującą użytkownika
W VS Code otwórz plik dataconnect/connector/mutations.gql
i dodaj mutację UpsertUser
:
mutation UpsertUser($username: String!) @auth(level: USER) {
user_upsert(
data: {
id_expr: "auth.uid"
username: $username
}
)
}
Tworzenie nowego użytkownika po zalogowaniu się
W Xcode otwórz plik FriendlyFlixApp.swift
i dodaj do inicjatora ten kod:
@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 {
...
}
}
Ten kod korzysta z wygenerowanego dla Ciebie upsertUserMutation
połączenia danych FirebaseupsertUserMutation
, aby wstawiać nowego użytkownika (lub aktualizować istniejącego użytkownika o tym samym identyfikatorze) za każdym razem, gdy użytkownik zarejestruje się za pomocą usługi Firebase Authentication.
Jak to działa w praktyce
Aby sprawdzić, czy to działa, najpierw zarejestruj się w aplikacji na iOS:
- Jeśli nie, zatrzymaj i uruchom ponownie emulator Firebase, aby upewnić się, że emulator uwierzytelniania Firebase działa.
- W Xcode kliknij przycisk Uruchom, aby uruchomić aplikację w symulatorze iOS.
- Kliknij ikonę awatara w prawym górnym rogu ekranu.
- Przejdź do procesu rejestracji i zarejestruj się w aplikacji.
Następnie wyślij zapytanie do bazy danych, aby sprawdzić, czy aplikacja utworzyła nowe konto użytkownika:
- W VS Code otwórz
dataconnect/schema/schema.gql
i kliknij Odczytaj dane w przypadku encjiUser
. - Spowoduje to utworzenie nowego pliku zapytania o nazwie
User_read.gql
. - Kliknij Uruchom lokalnie, aby wyświetlić wszystkich użytkowników w tabeli użytkowników.
- W panelu Wykonanie połączenia danych powinno być teraz widoczne konto użytkownika, który właśnie się zarejestrował
9. Zarządzanie ulubionymi filmami
W tej sekcji laboratorium kodowania zaimplementujesz interakcje użytkownika w aplikacji do oceniania filmów, a w szczególności umożliwisz użytkownikom zarządzanie ulubionymi filmami. Filmy oznaczone jako ulubione będą widoczne w sekcji listy Do obejrzenia w aplikacji.
Ulepsz schemat, aby obsługiwał ulubione
Typ FavoriteMovie
to tabela złączeń, która obsługuje relacje wiele do wielu między użytkownikami a ich ulubionymi filmami. Każda tabela łączy User
z Movie
.
Skopiuj fragment kodu i wklej go do pliku 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!
}
Określanie mutacji do dodawania i usuwania ulubionych
Zanim aplikacja będzie mogła wyświetlić ulubione filmy użytkownika, musi on wskazać, które są jego ulubionymi. Aby to zrobić, musisz najpierw dodać 2 mutacje, które odpowiednio oznaczą film jako ulubiony lub usuną go z ulubionych.
- W VS Code otwórz
mutations.gql
wdataconnect/connector/mutations.gql
. - Dodaj te mutacje, aby obsługiwać dodawanie filmów do ulubionych:
## 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 })
}
Łączenie mutacji z interfejsem aplikacji
Użytkownicy mogą oznaczyć film jako ulubiony, klikając ikonę serca na ekranie szczegółów filmu.
Aby połączyć utworzone mutacje z interfejsem aplikacji, wprowadź te zmiany w MovieCardView
:
- Zaimportuj
FriendlyFlixSDK
i skonfiguruj oprogramowanie sprzęgające.
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
...
}
- Zaimplementuj metodę
toggleFavourite
. Będzie wywoływana za każdym razem, gdy użytkownik kliknie ikonę serca wMovieCardView
:
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)
}
}
}
}
Spowoduje to zaktualizowanie stanu ulubionych bieżącego filmu w bazie danych. Ostatnim brakującym krokiem jest upewnienie się, że stan interfejsu użytkownika jest odpowiednio odzwierciedlony.
Zdefiniuj zapytanie, które pozwoli sprawdzić, czy film jest oznaczony jako ulubiony
- W VS Code otwórz
queries.gql
wdataconnect/connector
. - Aby sprawdzić, czy film jest oznaczony jako ulubiony, dodaj to zapytanie:
query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) {
movieId
}
}
- W Xcode utwórz instancję odwołania do zapytania
GetIfFavoritedMovie
i zaimplementuj obliczoną właściwość, która określa, czy film wyświetlany na tym ekranieMovieCardView
jest oznaczony jako ulubiony dla bieżącego użytkownika.
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
}
...
}
- Zaktualizuj kod w
toggleFavourite
, aby zapytanie było wykonywane za każdym razem, gdy użytkownik kliknie przycisk. Dzięki temu właściwość obliczonaisFavourite
zawsze zwraca prawidłową wartość.
private func toggleFavourite() {
Task {
if isFavourite {
...
}
let _ = try await isFavouriteRef.execute()
}
}
Pobieranie ulubionych filmów
Ostatnim krokiem w przypadku tej funkcji będzie pobranie ulubionych filmów użytkownika, aby mógł je zobaczyć na liście do obejrzenia.
- W VS Code otwórz plik
queries.gql
wdataconnect/connector/queries.gql
i wklej to zapytanie:
## 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
}
}
}
}
Lista ulubionych filmów użytkownika jest wyświetlana na stronie LibraryScreen
. Ten ekran powinien wyświetlać dane tylko wtedy, gdy użytkownik jest zalogowany, więc najpierw połącz stan uwierzytelniania ekranu z funkcją AuthenticationService
aplikacji.
- Dodawanie kodu do mapy z
FavoriteMovieFavoriteMovies
doMovie
doMovie+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
}
}
- W Xcode otwórz
LibraryScreen
, a potem zaktualizujisSignedIn
w ten sposób:
struct LibraryScreen: View {
...
private var isSignedIn: Bool {
authenticationService.user != nil
}
}
- Następnie zaimportuj Firebase Data Connect i FriendlyFlixSDK oraz uzyskaj odwołanie do
GetUserFavoriteMovies
zapytania:
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) ?? []
}
...
}
- Sprawdź, czy zapytanie
watchListRef
jest wykonywane, gdy pojawia się widok:
extension LibraryScreen: View {
var body: some View {
...
MovieListSection(namespace: namespace, title: "Watch List", movies: watchList)
.onAppear {
Task {
try await watchListRef.execute()
}
...
Jak to działa w praktyce
Możesz teraz uruchomić aplikację i wypróbować właśnie wdrożoną funkcję ulubionych. Kilka rzeczy, o których warto pamiętać:
- Sprawdź, czy emulator Firebase jest uruchomiony.
- Sprawdź, czy masz dodane dane testowe dotyczące filmów i szczegółów filmów.
- Upewnij się, że masz konto użytkownika
- W Xcode kliknij przycisk Uruchom, aby uruchomić aplikację w symulatorze iOS.
- Po uruchomieniu aplikacji kliknij kartę filmu, aby wyświetlić jego szczegóły.
- Kliknij ikonę serca, aby oznaczyć film jako ulubiony. Serce powinno się wypełnić.
- Powtórz tę czynność w przypadku kilku filmów.
- Otwórz kartę Biblioteka. Powinna pojawić się lista wszystkich filmów oznaczonych jako ulubione.
10. Gratulacje
Udało Ci się dodać Firebase Data Connect do aplikacji na iOS. Teraz znasz już najważniejsze kroki wymagane do skonfigurowania Data Connect, tworzenia zapytań i mutacji oraz obsługi uwierzytelniania użytkowników.
Opcjonalnie: wdrażanie w wersji produkcyjnej
Ta aplikacja korzystała do tej pory tylko z emulatorów Firebase. Jeśli chcesz dowiedzieć się, jak wdrożyć tę aplikację w prawdziwym projekcie Firebase, przejdź do następnego kroku.
11. (Opcjonalnie) Wdrażanie aplikacji
Dotychczas ta aplikacja działała w całości lokalnie, a wszystkie dane były przechowywane w Pakiecie emulatorów Firebase. W tej sekcji dowiesz się, jak skonfigurować projekt Firebase, aby ta aplikacja działała w środowisku produkcyjnym.
Włączanie Uwierzytelniania Firebase
- W konsoli Firebase otwórz sekcję Uwierzytelnianie i kliknij Rozpocznij.
- Otwórz kartę Metoda logowania .
- W sekcji dostawców natywnych wybierz opcję E-mail/hasło.
- Włącz dostawcę poczty e-mail/hasła, a następnie kliknij Zapisz.
Włączanie Firebase Data Connect
Ważne: jeśli wdrażasz schemat w projekcie po raz pierwszy, ten proces utworzy instancję Cloud SQL PostgreSQL, co może potrwać około 15 minut. Nie będzie można wdrożyć aplikacji, dopóki instancja Cloud SQL nie będzie gotowa i zintegrowana z usługą Firebase Data Connect.
1. W interfejsie rozszerzenia Firebase Data Connect w VS Code kliknij Wdróż w środowisku produkcyjnym. 2. Konieczne może być sprawdzenie zmian w schemacie i zatwierdzenie potencjalnie destrukcyjnych modyfikacji. Pojawi się prośba o: – sprawdzenie zmian schematu za pomocą firebase dataconnect:sql:diff
; – zastosowanie zmian, gdy uznasz, że możesz już to zrobić, korzystając z procesu rozpoczętego przez firebase dataconnect:sql:migrate
.
Instancja Cloud SQL for PostgreSQL zostanie zaktualizowana o ostatecznie wdrożony schemat i dane. Stan możesz śledzić w konsoli Firebase.
Teraz możesz kliknąć Uruchom (produkcja) w panelu Firebase Data Connect, tak jak w przypadku lokalnych emulatorów, aby dodać dane do środowiska produkcyjnego.
Zanim ponownie uruchomisz aplikację na iOS, upewnij się, że łączy się ona z instancją produkcyjną projektu:
- Otwórz menu Product (Produkt) > Scheme (Schemat) > Edit Scheme (Edytuj schemat)….
- W sekcji Uruchom odznacz argument uruchamiania
-useEmulator YES
.