Mem-build dengan Firebase Data Connect (iOS / Swift)

1. Ringkasan

Codelab ini memandu Anda melalui proses mengintegrasikan Firebase Data Connect dengan database Cloud SQL untuk membuat aplikasi ulasan film untuk iOS menggunakan SwiftUI

Anda akan mempelajari cara menghubungkan aplikasi iOS ke database Cloud SQL menggunakan Firebase Data Connect, sehingga memungkinkan sinkronisasi data yang lancar untuk ulasan film.

Di akhir codelab ini, Anda akan memiliki aplikasi iOS fungsional yang memungkinkan pengguna menjelajahi film, dan menandai film sebagai favorit, yang 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 rangkaian Firebase Emulator untuk waktu penyelesaian yang cepat.
  • Merancang skema database menggunakan Data Connect dan GraphQL.
  • Buat Swift SDK yang aman untuk jenis 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

  1. Login ke Firebase console menggunakan Akun Google Anda.
  2. Klik tombol untuk membuat project baru, lalu masukkan nama project (misalnya, Friendly Flix).
  3. Klik Lanjutkan.
  4. Jika diminta, tinjau dan setujui persyaratan Firebase, lalu klik Continue.
  5. (Opsional) Aktifkan bantuan AI di Firebase console (disebut "Gemini di Firebase").
  6. Untuk codelab ini, Anda tidak memerlukan Google Analytics, jadi nonaktifkan opsi Google Analytics.
  7. Klik Buat project, tunggu hingga project Anda disediakan, lalu 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.

  1. Di Firebase console, pilih Ringkasan Project di panel kiri.
  2. Klik tombol iOS+ untuk memilih platform. Saat diminta untuk memasukkan ID paket Apple, gunakan com.google.firebase.samples.FriendlyFlix
  3. Klik Register app dan ikuti petunjuk untuk mendownload file GoogleServices-Info.plist.
  4. Pindahkan file yang didownload ke direktori start/FriendlyFlix/app/FriendlyFlix/FriendlyFlix/ dari kode yang baru saja Anda download, menggantikan file GoogleServices-Info.plist yang ada.
  5. Kemudian, klik Next beberapa kali untuk menyelesaikan project penyiapan di Firebase console (Anda tidak perlu menambahkan SDK ke aplikasi, karena hal ini sudah ditangani untuk Anda di project starter).
  6. 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 telah dibundel sebelumnya, untuk membantu Anda mengelola skema dan menentukan kueri serta mutasi yang akan digunakan dalam aplikasi, dan menghasilkan SDK yang memiliki jenis yang kuat.

Setelah menjalankan skrip, VS Code akan terbuka secara otomatis.

Setelah melakukannya sekali, Anda dapat memulai VS Code dengan menjalankan VS Code di direktori lokal:

code .

Penginstalan manual

  1. Instal Visual Studio Code
  2. Instal Node.js.
  3. Di VS Code, buka direktori codelab-dataconnect-ios/FriendlyFlix.
  4. Instal ekstensi Firebase Data Connect dari Visual Studio Code Marketplace.

Menginisialisasi Data Connect dalam project

Di panel sebelah kiri, klik ikon Firebase untuk membuka UI ekstensi Data Connect VS Code

  1. Klik tombol Sign in with Google. Jendela browser akan terbuka; ikuti petunjuk untuk login ke ekstensi dengan Akun Google Anda.
  2. Klik tombol Hubungkan project Firebase, lalu pilih project yang Anda buat sebelumnya di konsol.
  3. 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 disetel ke friendly-flix, dan paket Swift ke FriendlyFlixSDK.

connectorId: "friendly-flix"
generate:
  swiftSdk:
    outputDir: "../../app"
    package: "FriendlyFlixSDK"
    observablePublisher: observableMacro

Berikut arti setelan ini:

  • connectorId - nama unik untuk konektor ini.
  • outputDir - jalur tempat SDK Data Connect yang dihasilkan akan disimpan. Jalur ini relatif terhadap direktori yang berisi file connector.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.

Mulai emulator Firebase

Di VS Code, beralihlah ke Firebase view, 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

  1. Membuka FriendlyFlix/app/FriendlyFlix/FriendlyFlix.xcodeproj di Xcode
  2. Pilih File > Add Package Dependencies...
  3. Klik Add Local..., lalu tambahkan paket FriendlyFlixSDK dari folder FriendlyFlix/app
  4. Tunggu hingga Xcode menyelesaikan dependensi paket.
  5. Dalam dialog Choose Package Products for FriendlyFlixSDK, pilih FriendlyFlix sebagai target, lalu klik Add Package.

Mengonfigurasi aplikasi iOS untuk menggunakan emulator lokal

  1. Buka FriendlyFlixApp.swift. (Anda dapat menekan CMD + Shift + O untuk membuka dialog Quick Open, lalu mengetik "FriendlyFlixApp" untuk menemukan file dengan cepat)
  2. Impor Firebase, Firebase Auth, Firebase Data Connect, dan SDK yang dihasilkan untuk skema Anda
  3. Di inisialisasi, konfigurasi Firebase.
  4. 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()
  }

  ...

}
  1. Pilih Simulator iOS di dropdown Tujuan.
  2. 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. Entitas seperti Movie, MovieMetaData, dan lainnya dipetakan ke tabel database, dengan hubungan yang dibuat menggunakan direktif skema GraphQL dan Firebase Data Connect.

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 Anda 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 ini menggunakan ekspresi seperti @default(expr: "uuidV4()") untuk membuat ID dan stempel waktu unik secara otomatis. Misalnya, kolom id dalam jenis Movie otomatis diisi dengan UUID saat record baru dibuat.

Masukkan data tiruan untuk film dan metadata film

Setelah skema ditentukan, Anda kini dapat mengisi otomatis database dengan data tiruan untuk pengujian.

  1. Di Finder, salin finish/FriendlyFlix/dataconnect/moviedata_insert.gql ke folder start/FriendlyFlix/dataconnect.
  2. Di VS Code, buka dataconnect/moviedata_insert.gql.
  3. Pastikan emulator di ekstensi Firebase Data Connect sedang berjalan.
  4. Anda akan melihat tombol Run (local) di bagian atas file. Klik ini untuk memasukkan data film tiruan ke dalam database Anda.
  5. Periksa terminal Eksekusi Koneksi Data 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 mengimplementasikan fitur untuk menampilkan daftar film.

Pertama, Anda akan mempelajari cara membuat kueri yang mengambil semua film dari tabel movies. Firebase Data Connect membuat kode untuk SDK yang aman untuk jenis, yang kemudian dapat Anda gunakan untuk menjalankan 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 mana 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 akan 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 Results pada terminal Eksekusi Data Connect.

Hubungkan kueri ListMovies ke layar utama aplikasi

Setelah menguji kueri di Emulator Koneksi Data, 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 listMoviesQuery() dibuat oleh Data Connect saat Anda menyimpan queries.gql. Untuk melihat implementasi Swift-nya, lihat file FriendlyFlixOperations.swift dalam paket FriendlyFlixSDK.

Menjalankan aplikasi

Di Xcode, klik tombol Run untuk meluncurkan aplikasi di iOS Simulator.

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 banner besar 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 bawahnya.

Saat ini, kueri ListMovies mengambil semua film. Untuk mengoptimalkan tampilan bagian ini, Anda akan membatasi jumlah film yang ditampilkan setiap kueri. Penerapan kueri ListMovies saat ini belum menawarkan dukungan bawaan untuk membatasi hasil - menambahkan dukungan untuk membatasi dan mengurutkan adalah sesuatu yang akan Anda tambahkan di bagian ini.

Meningkatkan kualitas kueri ListMovies

Buka queries.gql dan perbarui ListMovies sebagai berikut untuk menambahkan dukungan 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
  }
}

Hal 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 memperbarui 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, perbarui 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 penerapannya

Jalankan aplikasi lagi 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 menyadari bahwa detail tersebut kurang... detail.

Hal ini karena kita hanya mengambil detail tentang setiap film sebanyak yang kita butuhkan untuk merender bagian utama film dan bagian film teratas: judul film, deskripsi singkat, dan URL gambar.

Di halaman detail film, kita akan ingin menampilkan informasi selengkapnya tentang film tersebut. Di bagian ini, Anda akan meningkatkan kualitas aplikasi sehingga dapat menampilkan aktor film dan ulasan apa pun di halaman detail.

Untuk melakukannya, Anda harus melakukan beberapa hal:

  • Meningkatkan kualitas 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 kualitas 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

Setelah skema diperbarui, Anda kini dapat mengisi database dengan lebih banyak data tiruan untuk pengujian.

  1. Di Finder, salin finish/FriendlyFlix/dataconnect/moviededetails_insert.gql ke folder start/FriendlyFlix/dataconnect.
  2. Di VS Code, buka dataconnect/moviededetails_insert.gql.
  3. Pastikan emulator di ekstensi Firebase Data Connect sedang berjalan.
  4. Anda akan melihat tombol Run (local) di bagian atas file. Klik ini untuk memasukkan data film tiruan ke dalam database Anda.
  5. 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
    }
  }
}

Hubungkan 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 iOS Simulator.

Setelah aplikasi diluncurkan, ketuk kartu film untuk menampilkan detail film. Kodenya akan terlihat seperti berikut:

8. Menerapkan 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 mulai dengan mengizinkan pengguna menambahkan film ke daftar tontonan pribadi mereka.

Sebelum dapat menerapkan fitur daftar pantauan, Anda harus menetapkan identitas pengguna terlebih dahulu. Untuk mengaktifkannya, Anda akan mengintegrasikan Firebase Authentication, sehingga pengguna dapat login ke aplikasi.

Anda mungkin sudah melihat tombol avatar pengguna di kanan atas layar utama. Dengan mengetuknya, Anda akan diarahkan 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.

Aktifkan 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 Anda, temukan firebase.json dan perbarui seperti berikut untuk mengaktifkan emulator Firebase Authentication.

{
  "emulators": {
    "dataconnect": {
    },
    "auth": {
    }
  },
  "dataconnect": {
    "source": "dataconnect"
  }
}

Setelah itu, Anda perlu menghentikan dan memulai ulang Emulator Firebase agar perubahan diterapkan.

Menerapkan pengendali autentikasi

Di bagian berikut, Anda akan menerapkan logika yang menghubungkan autentikasi pengguna dengan database Anda. Hal ini melibatkan pembuatan handler autentikasi yang memproses login yang berhasil.

Setelah pengguna diautentikasi, handler 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 handler autentikasi generik yang memungkinkan Anda menggunakan onSignUp untuk mendaftarkan penutupan yang akan dipanggil saat pengguna telah login.

Di dalam penutupan tersebut, Anda kemudian dapat membuat akun pengguna baru di database. Namun, sebelum dapat melakukannya, Anda perlu membuat mutasi yang memungkinkan Anda membuat atau memperbarui pengguna baru dalam database.

Menambahkan entitas Pengguna ke skema

Jenis User menentukan entitas pengguna. Pengguna dapat berinteraksi dengan film dengan memberikan ulasan atau menandai film sebagai favorit.

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, dan 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 penerapannya

Untuk memverifikasi apakah ini berfungsi, daftar terlebih dahulu di aplikasi iOS:

  • Jika belum, hentikan dan mulai ulang Firebase Emulator untuk memastikan Firebase Authentication Emulator berjalan.
  • Di Xcode, klik tombol Run untuk meluncurkan aplikasi di iOS Simulator.
  • Klik ikon avatar di sudut kanan atas layar.
  • Beralih ke alur Daftar dan daftar ke aplikasi.

Kemudian, kueri database untuk memverifikasi bahwa aplikasi membuat akun pengguna baru untuk pengguna:

  • Di VS Code, buka dataconnect/schema/schema.gql, lalu klik Read data pada entitas User
  • Tindakan ini akan membuat file kueri baru, bernama User_read.gql
  • Klik Run local 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 kualitas skema untuk mendukung favorit

Jenis FavoriteMovie adalah tabel gabungan yang menangani hubungan many-to-many antara pengguna dan film favorit mereka. Setiap tabel menautkan User ke Movie.

Salin dan tempel cuplikan kode ke dalam 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!
}

Tentukan 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 film favorit pengguna, atau menghapusnya dari favoritnya lagi.

  1. Di VS Code, buka mutations.gql di dataconnect/connector/mutations.gql
  2. Tambahkan mutasi berikut untuk menangani pemberian tanda suka pada film:
## 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, lakukan perubahan berikut di MovieCardView:

  1. Impor FriendlyFlixSDK dan siapkan 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

  ...
}
  1. Terapkan metode toggleFavourite. Metode ini akan dipanggil setiap kali pengguna mengetuk ikon hati di MovieCardView:
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. Langkah terakhir yang belum dilakukan adalah memastikan status UI ditampilkan dengan tepat.

Menentukan kueri untuk mengetahui apakah film ditandai sebagai favorit

  1. Di VS Code, buka queries.gql di dataconnect/connector.
  2. 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
  }
}
  1. Di Xcode, buat instance referensi ke kueri GetIfFavoritedMovie dan terapkan properti terkomputasi yang menentukan apakah film yang ditampilkan di GetIfFavoritedMovie ini ditandai sebagai favorit untuk pengguna saat ini.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
  }

  ...

}
  1. Perbarui kode di toggleFavourite untuk menjalankan kueri setiap kali pengguna mengetuk tombol. Hal ini memastikan bahwa properti komputasi isFavourite 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 sehingga mereka dapat melihatnya di daftar tontonan.

  1. Di VS Code, buka queries.gql di dataconnect/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, jadi Anda harus menghubungkan status autentikasi layar terlebih dahulu ke AuthenticationService aplikasi.

  1. Tambahkan kode untuk memetakan dari FavoriteMovieFavoriteMovies ke Movie ke Movie+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
  }
}
  1. Di Xcode, buka LibraryScreen, lalu perbarui isSignedIn sebagai berikut:
struct LibraryScreen: View {
  ...

  private var isSignedIn: Bool {
    authenticationService.user != nil
  }

}
  1. Kemudian, impor Firebase Data Connect dan FriendlyFlixSDK, lalu 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) ?? []
  }

  ...

}


  1. Pastikan kueri watchListRef dijalankan 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 penerapannya

Sekarang Anda dapat menjalankan aplikasi dan mencoba fitur favorit yang baru saja Anda terapkan. 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
  1. Di Xcode, klik tombol Run untuk meluncurkan aplikasi di iOS Simulator.
  2. Setelah aplikasi diluncurkan, ketuk kartu film untuk menampilkan detail film.
  3. Ketuk ikon hati untuk menandai film sebagai favorit. Hati akan berubah menjadi penuh.
  4. Ulangi langkah ini untuk beberapa film.
  5. 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) Deploy aplikasi Anda

Sejauh ini, aplikasi ini sepenuhnya bersifat lokal, semua datanya ada di Firebase Emulator Suite. Di bagian ini, Anda akan mempelajari cara mengonfigurasi project Firebase agar aplikasi ini dapat berfungsi dalam produksi.

Aktifkan Firebase Authentication

  1. Di Firebase console, buka bagian Authentication, lalu klik Mulai.
  2. Buka tab Metode login .
  3. Pilih opsi Email/Sandi dari bagian penyedia asli,
  4. Aktifkan penyedia Email/Sandi, lalu klik Simpan.

Mengaktifkan Firebase Data Connect

Penting: Jika ini adalah pertama kalinya Anda men-deploy skema di project, proses ini akan membuat instance Cloud SQL PostgreSQL, yang dapat memakan 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 yang di-deploy terakhir. Anda dapat memantau status di Konsol Firebase.

Sekarang Anda dapat mengklik Jalankan (Produksi) 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:

  1. Buka menu Product > Scheme > Edit Scheme....
  2. Di bagian Run, hapus centang pada argumen peluncuran -useEmulator YES.