1. Ringkasan
Codelab ini memandu Anda melalui proses integrasi Firebase Data Connect dengan database Cloud SQL untuk mem-build aplikasi ulasan film untuk iOS menggunakan SwiftUI
Anda akan mempelajari cara menghubungkan aplikasi iOS ke database Cloud SQL menggunakan Firebase Data Connect, yang memungkinkan sinkronisasi data yang lancar untuk ulasan film.
Di akhir codelab ini, Anda akan memiliki aplikasi iOS yang berfungsi dan memungkinkan pengguna menjelajahi film, serta menandai film sebagai favorit, semuanya didukung oleh database Cloud SQL menggunakan kecanggihan Firebase Data Connect.
Yang akan Anda pelajari
Codelab ini akan mengajarkan cara:
- Siapkan Firebase Data Connect, menggunakan suite Firebase Emulator untuk waktu penyelesaian yang cepat.
- Buat desain skema database menggunakan Data Connect dan GraphQL.
- Buat Swift SDK typesafe dari skema database Anda dan tambahkan ke aplikasi Swift.
- Terapkan autentikasi pengguna dan integrasikan dengan Firebase Data Connect untuk mengamankan data pengguna Anda.
- Ambil, perbarui, hapus, dan kelola data di Cloud SQL menggunakan kueri dan mutasi yang didukung oleh GraphQL.
- (Opsional) Deploy layanan Data Connect ke produksi.
Prasyarat
- Xcode versi terbaru
- Kode contoh codelab. Anda akan mendownload kode contoh di salah satu langkah pertama codelab.
2. Menyiapkan project contoh
Membuat project Firebase
- Login ke Firebase console dengan akun Google Anda.
- Di Firebase console, klik Create a Firebase project.
- Masukkan nama untuk project Firebase Anda (misalnya, "Friendly Flix"), lalu klik Continue.
- Anda mungkin diminta untuk mengaktifkan bantuan AI untuk project Firebase Anda. Untuk tujuan codelab ini, pilihan Anda tidak masalah.
- Anda mungkin diminta untuk mengaktifkan Google Analytics. Untuk tujuan codelab ini, pilihan Anda tidak masalah.
- Setelah sekitar satu menit, project Firebase Anda akan siap. Klik Lanjutkan.
Mendownload kode
Jalankan perintah berikut untuk meng-clone kode contoh untuk codelab ini. Tindakan ini akan membuat direktori bernama codelab-dataconnect-ios
di komputer Anda:
git clone https://github.com/FirebaseExtended/codelab-dataconnect-ios`
Jika tidak memiliki git di komputer, Anda juga dapat mendownload kode langsung dari GitHub.
Menambahkan konfigurasi Firebase
Firebase SDK menggunakan file konfigurasi untuk terhubung ke project Firebase Anda. Di platform Apple, file ini disebut GoogleServices-Info.plist
. Pada langkah ini, Anda akan mendownload file konfigurasi dan menambahkannya ke project Xcode.
- Di Firebase console, pilih Project Overview di panel navigasi sebelah kiri.
- Klik tombol iOS+ untuk memilih platform. Saat diminta memasukkan ID paket Apple, gunakan
com.google.firebase.samples.FriendlyFlix
- Klik Register app dan ikuti petunjuk untuk mendownload file
GoogleServices-Info.plist
. - Pindahkan file yang didownload ke direktori
start/FriendlyFlix/app/FriendlyFlix/FriendlyFlix/
kode yang baru saja Anda download, yang akan mengganti fileGoogleServices-Info.plist
yang ada. - Kemudian, klik Berikutnya beberapa kali untuk menyelesaikan project penyiapan di Firebase console (Anda tidak perlu menambahkan SDK ke aplikasi, karena hal ini telah dilakukan untuk Anda di project awal).
- Terakhir, klik Lanjutkan ke konsol untuk menyelesaikan proses penyiapan.
3. Menyiapkan Data Connect
Penginstalan
Penginstalan otomatis
Jalankan perintah berikut di direktori codelab-dataconnect-ios/FriendlyFlix
:
curl -sL https://firebase.tools/dataconnect | bash
Skrip ini mencoba menyiapkan lingkungan pengembangan untuk Anda dan meluncurkan IDE berbasis browser. IDE ini menyediakan alat, termasuk ekstensi VS Code yang dipaketkan sebelumnya, untuk membantu Anda mengelola skema dan menentukan kueri serta mutasi yang akan digunakan dalam aplikasi, serta membuat SDK dengan jenis yang kuat.
Setelah menjalankan skrip, VS Code akan otomatis terbuka.
Setelah melakukannya sekali, Anda dapat memulai VS Code dengan menjalankan VS Code di direktori lokal:
code .
Penginstalan manual
- Menginstal Visual Studio Code
- Menginstal Node.js
- Di VS Code, buka direktori
codelab-dataconnect-ios/FriendlyFlix
. - Instal ekstensi Firebase Data Connect dari Visual Studio Code Marketplace.
Melakukan inisialisasi Data Connect dalam project
Di panel sebelah kiri, klik ikon Firebase untuk membuka UI ekstensi Data Connect VS Code
- Klik tombol Sign in with Google. Jendela browser akan terbuka; ikuti petunjuk untuk login ke ekstensi dengan Akun Google Anda.
- Klik tombol Connect a Firebase project dan pilih project yang Anda buat sebelumnya di konsol.
- Klik tombol Run firebase init dan ikuti langkah-langkah di terminal terintegrasi.
Mengonfigurasi pembuatan SDK
Setelah Anda mengklik tombol Run firebase init, ekstensi Firebase Data Connect akan melakukan inisialisasi direktori dataconnect
untuk Anda.
Di VS Code, buka file dataconnect/connector/connector.yaml
dan Anda akan menemukan konfigurasi default.
Perbarui konfigurasi dan gunakan setelan berikut untuk memastikan kode yang dihasilkan berfungsi dengan codelab ini. Secara khusus, pastikan connectorId
ditetapkan ke friendly-flix
, dan paket Swift ke FriendlyFlixSDK
.
connectorId: "friendly-flix"
generate:
swiftSdk:
outputDir: "../../app"
package: "FriendlyFlixSDK"
observablePublisher: observableMacro
Berikut adalah arti setelan ini:
connectorId
- nama unik untuk konektor ini.outputDir
- jalur tempat Data Connect SDK yang dihasilkan akan disimpan. Jalur ini relatif terhadap direktori yang berisi fileconnector.yaml
.package
- nama paket yang akan digunakan untuk paket Swift yang dihasilkan.
Setelah Anda menyimpan file ini, Firebase Data Connect akan membuat paket Swift bernama FriendlyFlixSDK
untuk Anda, dan menempatkannya di samping folder project FriendlyFlix
.
Memulai emulator Firebase
Di VS Code, beralihlah ke tampilan Firebase, lalu klik tombol Start emulators.
Tindakan ini akan memulai Firebase Emulator di terminal terintegrasi. Output-nya akan terlihat seperti ini:
npx -y firebase-tools@latest emulators:start --project <your-project-id>
Menambahkan paket yang dihasilkan ke aplikasi Swift Anda
- Buka
FriendlyFlix/app/FriendlyFlix/FriendlyFlix.xcodeproj
di Xcode - Pilih File > Add Package Dependencies...
- Klik Add Local..., lalu tambahkan paket
FriendlyFlixSDK
dari folderFriendlyFlix/app
- Tunggu hingga Xcode menyelesaikan dependensi paket.
- Pada dialog Choose Package Products for FriendlyFlixSDK, pilih
FriendlyFlix
sebagai target, lalu klik Add Package.
Mengonfigurasi aplikasi iOS untuk menggunakan emulator lokal
- Buka
FriendlyFlixApp.swift
. (Anda dapat menekan CMD + Shift + O untuk membuka dialog Quick Open, lalu mengetik "FriendlyFlixApp" untuk menemukan file dengan cepat) - Mengimpor Firebase, Firebase Auth, Firebase Data Connect, dan SDK yang dihasilkan untuk skema Anda
- Di penginisialisasi, konfigurasikan Firebase.
- Pastikan DataConnect dan Firebase Auth menggunakan emulator lokal.
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()
}
...
}
- Pilih Simulator iOS di dropdown Destination.
- Tekan CMD+R (atau klik tombol Run) di Xcode untuk menjalankan aplikasi di Simulator.
4. Menentukan skema dan mengisi otomatis database
Di bagian ini, Anda akan menentukan struktur dan hubungan antara entitas utama dalam aplikasi film dalam skema. Entity seperti Movie
, MovieMetaData
, dan lainnya dipetakan ke tabel database, dengan hubungan yang dibuat menggunakan Firebase Data Connect dan perintah skema GraphQL.
Entitas dan Hubungan Inti
Model data untuk aplikasi pelacak film ini terdiri dari beberapa entitas yang akan Anda buat selama codelab ini. Anda akan membuat entity inti terlebih dahulu, dan - saat menerapkan lebih banyak fitur - Anda akan menambahkan entity yang diperlukan untuk fitur tersebut.
Pada langkah ini, Anda akan membuat jenis Movie
dan MovieMetadata
.
Film
Jenis Movie
menentukan struktur utama untuk entity film, termasuk kolom seperti title
, genre
, releaseYear
, dan rating
.
Di VS Code, tambahkan definisi jenis Movie
ke 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
Jenis MovieMetadata
menetapkan hubungan satu-ke-satu dengan jenis Movie
. Data ini mencakup data tambahan seperti sutradara film.
Tambahkan definisi tabel MovieMetadata
ke file dataconnect/schema/schema.gql
:
type MovieMetadata @table {
movie: Movie! @ref
director: String
}
Kolom dan Default yang Dibuat Otomatis
Skema menggunakan ekspresi seperti @default(expr: "uuidV4()")
untuk membuat ID dan stempel waktu unik secara otomatis. Misalnya, kolom id
dalam jenis Movie
akan otomatis diisi dengan UUID saat data baru dibuat.
Memasukkan data tiruan untuk film dan metadata film
Dengan skema yang ditentukan, Anda kini dapat mengisi otomatis database dengan data tiruan untuk pengujian.
- Di Finder, salin
finish/FriendlyFlix/dataconnect/moviedata_insert.gql
ke folderstart/FriendlyFlix/dataconnect
. - Di VS Code, buka
dataconnect/moviedata_insert.gql
. - Pastikan emulator di ekstensi Firebase Data Connect sedang berjalan.
- Anda akan melihat tombol Run (local) di bagian atas file. Klik ini untuk menyisipkan data film tiruan ke dalam database Anda.
- Periksa terminal Data Connect Execution untuk mengonfirmasi bahwa data berhasil ditambahkan.
Setelah data tersedia, lanjutkan ke langkah berikutnya untuk mempelajari cara membuat kueri di Data Connect.
5. Mengambil dan menampilkan film
Di bagian ini, Anda akan menerapkan fitur untuk menampilkan daftar film.
Pertama, Anda akan mempelajari cara membuat kueri yang mengambil semua film dari tabel movies
. Firebase Data Connect menghasilkan kode untuk SDK typesafe yang kemudian dapat Anda gunakan untuk mengeksekusi kueri dan menampilkan film yang diambil di UI aplikasi Anda.
Menentukan kueri ListMovies
Kueri di Firebase Data Connect ditulis dalam GraphQL, sehingga Anda dapat menentukan kolom yang akan diambil. Di FriendlyFlix, layar yang menampilkan film memerlukan kolom berikut: title
, description
, releaseYear
, rating
, dan imageUrl
. Selain itu, karena ini adalah aplikasi SwiftUI, Anda memerlukan id
untuk membantu identitas tampilan SwiftUI.
Di VS Code, buka file dataconnect/connector/queries.gql
dan tambahkan kueri ListMovies
:
query ListMovies @auth(level: PUBLIC) {
movies {
id
title
imageUrl
releaseYear
genre
rating
tags
description
}
}
Untuk menguji kueri baru, klik tombol Run (local) untuk menjalankan kueri terhadap database lokal Anda. Daftar film dari database akan ditampilkan di bagian Hasil di terminal Eksekusi Data Connect.
Menghubungkan kueri ListMovies ke layar utama aplikasi
Setelah menguji kueri di Emulator Data Connect, Anda dapat memanggil kueri dari dalam aplikasi.
Saat Anda menyimpan queries.gql
, Firebase Data Connect akan membuat kode yang sesuai dengan kueri ListMovies
dalam paket FriendlyFlixSDK
.
Di Xcode, buka Movie+DataConnect.swift
, lalu tambahkan kode berikut untuk memetakan dari ListMoviesQuery.Data.Movie
ke 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
}
}
Buka file HomeScreen.swift
dan perbarui menggunakan cuplikan kode berikut.
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) ?? []
}
...
}
Kueri |
Menjalankan aplikasi
Di Xcode, klik tombol Run untuk meluncurkan aplikasi di Simulator iOS.
Setelah aplikasi diluncurkan, Anda akan melihat layar yang terlihat seperti ini:
Anda mungkin melihat bahwa semua area aplikasi (bagian hero, film teratas, dan daftar tontonan) menampilkan daftar yang sama. Hal ini karena Anda menggunakan kueri yang sama untuk semua tampilan tersebut. Di bagian berikutnya, Anda akan menerapkan kueri kustom. |
6. Menampilkan film utama dan film teratas
Pada langkah ini, Anda akan berfokus untuk memperbarui cara film ditampilkan di bagian hero – yaitu carousel yang terlihat jelas di bagian atas layar utama – dan juga di bagian film teratas di bawah.
Saat ini, kueri ListMovies mengambil semua film. Untuk mengoptimalkan tampilan bagian ini, Anda akan membatasi jumlah film yang ditampilkan oleh setiap kueri. Implementasi kueri ListMovies
saat ini belum menawarkan dukungan bawaan untuk membatasi hasil. Anda akan menambahkan dukungan untuk pembatasan dan pengurutan di bagian ini.
Meningkatkan kueri ListMovies
Buka queries.gql
dan perbarui ListMovies
sebagai berikut untuk menambahkan dukungan untuk pengurutan dan pembatasan:
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
}
}
Tindakan ini akan memungkinkan Anda membatasi jumlah film yang ditampilkan kueri, dan mengurutkan kumpulan hasil berdasarkan rating dan tahun rilis.
Setelah Anda menyimpan file ini, Firebase Data Connect akan otomatis membuat ulang kode dalam FriendlyFlixSDK
. Pada langkah berikutnya, Anda dapat mengupdate kode di HomeScreen.swift
untuk memanfaatkan fitur tambahan ini.
Menggunakan kueri yang ditingkatkan di UI
Kembali ke Xcode untuk membuat perubahan yang diperlukan pada HomeScreen.swift
.
Pertama, update heroMoviesRef
untuk mengambil 3 film yang baru dirilis:
struct HomeScreen {
...
init() {
heroMoviesRef = connector.listMoviesQuery
.ref { optionalVars in
optionalVars.limit = 3
optionalVars.orderByReleaseYear = .DESC
}
}
}
Selanjutnya, siapkan referensi kueri lain untuk film teratas, dan tetapkan filter ke 5 film dengan rating tertinggi:
struct HomeScreen {
...
let topMoviesRef: QueryRefObservation<ListMoviesQuery.Data, ListMoviesQuery.Variables>
init() {
heroMoviesRef = ...
topMoviesRef = connector.listMoviesQuery
.ref { optionalVars in
optionalVars.limit = 5
optionalVars.orderByRating = .DESC
}
}
}
Terakhir, perbarui properti komputasi yang menghubungkan hasil kueri ini ke UI:
extension HomeScreen {
...
private var topMovies: [Movie] {
topMoviesRef.data?.movies.map(Movie.init) ?? []
}
}
Lihat cara kerjanya
Jalankan kembali aplikasi untuk melihat 3 film terbaru di bagian hero, dan 5 film dengan rating tertinggi di bagian film teratas:
7. Menampilkan detail film dan aktor
Pengguna kini dapat menjelajahi film. Saat mengetuk kartu film, mereka akan melihat beberapa detail tentang film tersebut, tetapi Anda mungkin telah melihat bahwa detailnya kurang detail.
Hal ini karena kita hanya mengambil detail sebanyak mungkin tentang setiap film yang diperlukan untuk merender bagian hero film dan bagian film teratas: judul film, deskripsi singkat, dan URL gambar.
Di halaman detail film, kita ingin menampilkan informasi selengkapnya tentang film tersebut. Di bagian ini, Anda akan meningkatkan aplikasi agar dapat menampilkan aktor film dan ulasan apa pun di halaman detail.
Untuk melakukannya, Anda harus melakukan beberapa hal:
- Meningkatkan skema untuk mendukung aktor dan ulasan film
- Menulis kueri Firebase Data Connect untuk mengambil detail tentang film tertentu
- Menampilkan hasil di layar detail film
Meningkatkan skema
Di VS Code, buka dataconnect/schema/schema.gql
dan tambahkan definisi skema untuk Actor
dan 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"
}
Menambahkan data tiruan untuk aktor
Dengan skema yang diperbarui, Anda kini dapat mengisi database dengan lebih banyak data tiruan untuk pengujian.
- Di Finder, salin
finish/FriendlyFlix/dataconnect/moviededetails_insert.gql
ke folderstart/FriendlyFlix/dataconnect
. - Di VS Code, buka
dataconnect/moviededetails_insert.gql
. - Pastikan emulator di ekstensi Firebase Data Connect sedang berjalan.
- Anda akan melihat tombol Run (local) di bagian atas file. Klik ini untuk menyisipkan data film tiruan ke dalam database Anda.
- Periksa terminal Eksekusi Data Connect untuk mengonfirmasi bahwa data berhasil ditambahkan.
Setelah data tersedia, lanjutkan ke langkah berikutnya untuk menentukan kueri guna mengambil detail film.
Menentukan kueri GetMovieById
Di VS Code, buka file dataconnect/connector/queries.gql
dan tambahkan kueri 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
}
}
}
Menghubungkan kueri GetMovieById ke MovieDetailsView
Di Xcode, buka file MovieDetailsView.swift
dan perbarui properti komputasi movieDetails
agar cocok dengan kode berikut:
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
}
}
Menjalankan aplikasi
Di Xcode, klik tombol Run untuk meluncurkan aplikasi di Simulator iOS.
Setelah aplikasi diluncurkan, ketuk kartu film untuk menampilkan detail film. Kodenya akan terlihat seperti berikut:
8. Mengimplementasikan autentikasi pengguna
Saat ini, aplikasi menampilkan informasi film dan aktor yang tidak dipersonalisasi. Pada langkah-langkah berikut, Anda akan menerapkan fitur yang mengaitkan data dengan pengguna yang login. Anda akan memulai dengan mengizinkan pengguna menambahkan film ke daftar tontonan pribadi mereka.
Sebelum dapat menerapkan fitur daftar yang dipantau, Anda harus menetapkan identitas pengguna terlebih dahulu. Untuk mengaktifkannya, Anda akan mengintegrasikan Firebase Authentication, yang memungkinkan pengguna login ke aplikasi.
Anda mungkin telah melihat tombol avatar pengguna di kanan atas layar utama. Mengetuk tombol ini akan mengarahkan Anda ke layar tempat pengguna dapat mendaftar atau login menggunakan email dan sandi mereka.
Setelah pengguna berhasil login, aplikasi Anda harus menyimpan detail penting mereka, terutama ID pengguna unik dan nama pengguna yang dipilih.
Mengaktifkan Firebase Authentication
Di Firebase console untuk project Anda, buka bagian Authentication, lalu aktifkan Firebase Authentication. Kemudian, aktifkan penyedia autentikasi Email/Sandi.
Di folder project lokal, temukan firebase.json
dan perbarui seperti berikut untuk mengaktifkan emulator Firebase Authentication.
{
"emulators": {
"dataconnect": {
},
"auth": {
}
},
"dataconnect": {
"source": "dataconnect"
}
}
Setelah itu, Anda harus menghentikan dan memulai ulang Firebase Emulator agar perubahan diterapkan.
Menerapkan pengendali autentikasi
Di bagian berikut, Anda akan menerapkan logika yang menghubungkan autentikasi pengguna dengan database. Hal ini melibatkan pembuatan pengendali autentikasi yang memproses login yang berhasil.
Setelah pengguna diautentikasi, pengendali ini akan otomatis memicu pembuatan akun yang sesuai di database Anda.
Di Xcode, buka file AuthenticationService.swift
dan tambahkan kode berikut:
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
}
}
Ini adalah pengendali autentikasi generik yang memungkinkan Anda menggunakan onSignUp
untuk mendaftarkan penutupan yang akan dipanggil saat pengguna login.
Di dalam penutupan tersebut, Anda dapat membuat akun pengguna baru di database. Namun, sebelum dapat melakukannya, Anda perlu membuat mutasi yang memungkinkan Anda membuat atau memperbarui pengguna baru di database.
Menambahkan entitas Pengguna ke skema
Jenis User
menentukan entity pengguna. Pengguna dapat berinteraksi dengan film dengan memberikan ulasan atau memfavoritkan film.
Di VS Code, buka file dataconnect/schema/schema.gql
dan tambahkan definisi tabel User
berikut:
## 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)")
}
Menentukan mutasi untuk menyisipkan atau memperbarui pengguna
Di VS Code, buka file dataconnect/connector/mutations.gql
dan tambahkan mutasi UpsertUser
:
mutation UpsertUser($username: String!) @auth(level: USER) {
user_upsert(
data: {
id_expr: "auth.uid"
username: $username
}
)
}
Membuat pengguna baru setelah berhasil login
Di Xcode, buka FriendlyFlixApp.swift
, lalu tambahkan kode berikut ke penginisialisasi:
@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 {
...
}
}
Kode ini menggunakan upsertUserMutation
Firebase Data Connect yang dibuat untuk Anda guna menyisipkan pengguna baru (atau memperbarui pengguna yang ada dengan ID yang sama) setiap kali pengguna berhasil mendaftar menggunakan Firebase Authentication.
Lihat cara kerjanya
Untuk memverifikasi bahwa hal ini berfungsi, daftar terlebih dahulu di aplikasi iOS:
- Jika belum, hentikan dan mulai ulang Firebase Emulator untuk memastikan Firebase Authentication Emulator sedang berjalan.
- Di Xcode, klik tombol Run untuk meluncurkan aplikasi di Simulator iOS.
- Klik ikon avatar di sudut kanan atas layar.
- Beralih ke alur Daftar dan daftar ke aplikasi.
Kemudian, buat kueri database untuk memverifikasi bahwa aplikasi telah membuat akun pengguna baru untuk pengguna:
- Di VS Code, buka
dataconnect/schema/schema.gql
dan klik Read data pada entitasUser
- Tindakan ini akan membuat file kueri baru, bernama
User_read.gql
- Klik Jalankan lokal untuk melihat semua pengguna di tabel pengguna
- Di panel Eksekusi Koneksi Data, Anda akan melihat akun untuk pengguna yang baru saja Anda daftarkan dengan
9. Mengelola film favorit
Di bagian codelab ini, Anda akan menerapkan interaksi pengguna di aplikasi ulasan film, khususnya memungkinkan pengguna mengelola film favorit mereka. Film yang ditandai sebagai favorit akan muncul di bagian daftar tontonan aplikasi.
Meningkatkan skema untuk mendukung favorit
Jenis FavoriteMovie
adalah tabel join yang menangani hubungan many-to-many antara pengguna dan film favorit mereka. Setiap tabel menautkan User
ke Movie
.
Salin dan tempel cuplikan kode ke file dataconnect/schema/schema.gql
Anda:
type FavoriteMovie
@table(name: "FavoriteMovies", singular: "favorite_movie", plural: "favorite_movies", key: ["user", "movie"]) {
## @ref is implicit
user: User!
movie: Movie!
}
Menentukan mutasi untuk menambahkan dan menghapus favorit
Sebelum aplikasi dapat menampilkan film favorit pengguna, pengguna harus menunjukkan film mana yang merupakan favoritnya. Untuk melakukannya, Anda harus menambahkan dua mutasi terlebih dahulu untuk menandai film sebagai salah satu favorit pengguna, atau menghapusnya dari favorit mereka lagi.
- Di VS Code, buka
mutations.gql
didataconnect/connector/mutations.gql
- Tambahkan mutasi berikut untuk menangani film favorit:
## 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 })
}
Menghubungkan mutasi ke UI aplikasi Anda
Pengguna dapat menandai film sebagai favorit dengan mengklik ikon hati di layar detail film.
Untuk menghubungkan mutasi yang baru saja Anda buat ke UI aplikasi, buat perubahan berikut di MovieCardView
:
- Mengimpor
FriendlyFlixSDK
dan menyiapkan konektor
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
...
}
- Implementasikan metode
toggleFavourite
. Metode ini akan dipanggil setiap kali pengguna mengetuk ikon hati diMovieCardView
:
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)
}
}
}
}
Tindakan ini akan memperbarui status favorit film saat ini di database. Satu langkah terakhir yang tidak ada adalah memastikan status UI ditampilkan sebagaimana mestinya.
Menentukan kueri untuk mengetahui apakah film ditandai sebagai favorit
- Di VS Code, buka
queries.gql
didataconnect/connector
. - Tambahkan kueri berikut untuk memeriksa apakah film ditandai sebagai favorit:
query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) {
movieId
}
}
- Di Xcode, Buat instance referensi ke kueri
GetIfFavoritedMovie
dan terapkan properti yang dihitung yang menentukan apakah film yang ditampilkan diMovieCardView
ini ditandai sebagai favorit untuk pengguna saat ini.
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
}
...
}
- Perbarui kode di
toggleFavourite
untuk menjalankan kueri setiap kali pengguna mengetuk tombol. Hal ini memastikan bahwa properti yang dihitungisFavourite
selalu menampilkan nilai yang benar.
private func toggleFavourite() {
Task {
if isFavourite {
...
}
let _ = try await isFavouriteRef.execute()
}
}
Mengambil film favorit
Sebagai langkah terakhir untuk fitur ini, Anda akan menerapkan pengambilan film favorit pengguna agar mereka dapat melihatnya di daftar tontonan.
- Di VS Code, buka
queries.gql
didataconnect/connector/queries.gql
dan tempel kueri berikut:
## 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
}
}
}
}
Daftar film favorit pengguna ditampilkan di LibraryScreen
. Layar ini hanya boleh menampilkan data jika pengguna login, sehingga Anda akan menghubungkan status autentikasi layar ke AuthenticationService
aplikasi terlebih dahulu.
- Tambahkan kode untuk memetakan dari
FavoriteMovieFavoriteMovies
keMovie
keMovie+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
}
}
- Di Xcode, buka
LibraryScreen
, lalu perbaruiisSignedIn
sebagai berikut:
struct LibraryScreen: View {
...
private var isSignedIn: Bool {
authenticationService.user != nil
}
}
- Kemudian, impor Firebase Data Connect dan FriendlyFlixSDK, dan dapatkan referensi ke kueri
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) ?? []
}
...
}
- Pastikan kueri
watchListRef
dieksekusi saat tampilan muncul:
extension LibraryScreen: View {
var body: some View {
...
MovieListSection(namespace: namespace, title: "Watch List", movies: watchList)
.onAppear {
Task {
try await watchListRef.execute()
}
...
Lihat cara kerjanya
Sekarang Anda dapat menjalankan aplikasi dan mencoba fitur favorit yang baru saja diterapkan. Beberapa hal yang perlu diingat:
- Pastikan Emulator Firebase sedang berjalan
- Pastikan Anda telah menambahkan data tiruan untuk film dan detail film
- Pastikan Anda telah mendaftar sebagai pengguna
- Di Xcode, klik tombol Run untuk meluncurkan aplikasi di Simulator iOS.
- Setelah aplikasi diluncurkan, ketuk kartu film untuk menampilkan detail film.
- Ketuk ikon hati untuk menandai film sebagai favorit. Hati akan berubah menjadi solid.
- Ulangi langkah ini untuk beberapa film.
- Buka tab Koleksi. Sekarang Anda akan melihat daftar semua film yang Anda tandai sebagai favorit.
10. Selamat
Selamat, Anda telah berhasil menambahkan Firebase Data Connect ke aplikasi iOS. Sekarang Anda sudah mengetahui langkah-langkah utama yang diperlukan untuk menyiapkan Data Connect, membuat kueri dan mutasi, serta menangani autentikasi pengguna.
Opsional: men-deploy ke produksi
Sejauh ini, aplikasi ini hanya menggunakan Emulator Firebase. Jika Anda ingin mempelajari cara men-deploy aplikasi ini ke project Firebase sungguhan, lanjutkan ke langkah berikutnya.
11. (Opsional) Men-deploy aplikasi
Sejauh ini aplikasi ini sepenuhnya bersifat lokal, semua datanya terdapat di Firebase Emulator Suite. Di bagian ini, Anda akan mempelajari cara mengonfigurasi project Firebase agar aplikasi ini dapat berfungsi dalam produksi.
Mengaktifkan Firebase Authentication
- Di Firebase console, buka bagian Authentication, lalu klik Get started.
- Buka tab Metode login .
- Pilih opsi Email/Sandi dari bagian penyedia native,
- Aktifkan penyedia Email/Sandi, lalu klik Simpan.
Mengaktifkan Firebase Data Connect
Penting: Jika ini adalah pertama kalinya Anda men-deploy skema dalam project, proses ini akan membuat instance PostgreSQL Cloud SQL, yang dapat memerlukan waktu sekitar 15 menit. Anda tidak akan dapat men-deploy hingga instance Cloud SQL siap dan terintegrasi dengan Firebase Data Connect.
1. Di UI ekstensi Firebase Data Connect VS Code, klik Deploy to production. 2. Anda mungkin perlu meninjau perubahan skema dan menyetujui modifikasi yang berpotensi merusak. Anda akan diminta untuk: - Meninjau perubahan skema menggunakan firebase dataconnect:sql:diff
- Jika Anda puas dengan perubahan, terapkan perubahan tersebut menggunakan alur yang dimulai oleh firebase dataconnect:sql:migrate
Instance Cloud SQL untuk PostgreSQL Anda akan diperbarui dengan skema dan data akhir yang di-deploy. Anda dapat memantau statusnya di Firebase Console.
Sekarang Anda dapat mengklik Run (Production) di panel Firebase Data Connect, seperti yang Anda lakukan dengan emulator lokal, untuk menambahkan data ke lingkungan produksi.
Sebelum menjalankan aplikasi iOS lagi, pastikan aplikasi terhubung ke instance produksi project Anda:
- Buka menu Product > Scheme > Edit Scheme....
- Di bagian Run, hapus centang pada argumen peluncuran
-useEmulator YES
.