運用 Firebase Data Connect 建構內容 (Android)

1. 總覽

ddc52cd46f923cf1.png

在本程式碼研究室中,您將整合 Firebase Data Connect 與 Cloud SQL 資料庫,以建構電影評論 Android 應用程式。您將瞭解如何:

  • 為 Firebase Data Connect 編寫 GraphQL 結構定義
  • 編寫查詢和變異
  • 實作使用者驗證機制,確保資料安全

事前準備

  • 最新版 Android Studio
  • 搭載 API 級別 23 以上版本的 Android 模擬器

課程內容

  • 如何使用本機模擬器設定 Firebase Data Connect。
  • 如何使用 Data Connect 和 GraphQL 設計資料結構定義。
  • 如何為電影評論應用程式編寫查詢和變異。
  • 如何產生 Kotlin SDK,並在 Android 應用程式中使用。
  • (選用) 如何將 Data Connect 服務部署至實際工作環境。

2. 設定範例專案

建立 Firebase 專案

  1. 使用 Google 帳戶登入 Firebase 主控台
  2. Firebase 控制台中,按一下「新增專案」。
  3. 輸入 Firebase 專案名稱 (例如「Movie Review」),然後按一下「繼續」。
  4. 系統可能會要求您啟用 Google Analytics,但在本程式碼研究室中,您的選擇不影響結果。
  5. 大約一分鐘後,Firebase 專案就會準備就緒。按一下「繼續」。

下載程式碼

執行下列指令,複製這個程式碼研究室的範例程式碼。這會在電腦上建立名為 codelab-dataconnect-android 的目錄:

git clone https://github.com/firebaseextended/codelab-dataconnect-android.git

如果您的電腦上沒有 Git,也可以直接從 GitHub 下載程式碼

新增 Firebase 設定

  1. Firebase 控制台中,選取左側導覽面板中的「專案總覽」。按一下 Android 按鈕選取平台。當系統提示您輸入套件名稱時,請使用 com.google.firebase.example.dataconnect
  2. 按一下「註冊應用程式」,然後按照操作說明下載 google-services.json 檔案,並將該檔案移至剛才下載程式碼的 app/ 目錄中。然後點選「下一步」。

3. 設定 Data Connect

安裝

自動安裝

codelab-dataconnect-android 目錄中執行下列指令:

curl -sL https://firebase.tools/dataconnect | bash

這個指令碼會嘗試為您設定開發環境,並啟動瀏覽器式 IDE。這個 IDE 提供工具 (包括預先內含的 VS Code 擴充功能),協助您管理結構定義,並定義應用程式要使用的查詢和變異,以及產生強型別 SDK。

執行指令碼後,VS Code 應會自動開啟。

注意:如果您已安裝 VS Code 的電腦版,系統應會自動開啟該版。如果指令碼安裝失敗,請按照下方的手動安裝步驟操作。

手動安裝

  1. 安裝 Visual Studio Code
  2. 安裝 Node.js
  3. 在 VS Code 中開啟 codelab-dataconnect-android 目錄。
  4. 前往 Visual Studio Code Marketplace 安裝 Firebase Data Connect 擴充功能。

在專案中初始化 Data Connect

在左側面板中,按一下 Firebase 圖示,開啟 Data Connect VS Code 擴充功能 UI:

  1. 點選「使用 Google 帳戶登入」按鈕。瀏覽器視窗隨即開啟,請按照操作說明使用 Google 帳戶登入擴充功能。ef59f25a9e9cbfff.png
  2. 按一下「連結 Firebase 專案」按鈕,然後選取您先前在控制台中建立的專案。951a836ba0682494.png

按一下「Run firebase init」按鈕,然後按照整合式終端機中的步驟操作。

設定 SDK 產生作業

點選「Run firebase init」按鈕後,Firebase Data Connect 擴充功能應會為您初始化 dataconnect/ 目錄。

在 VS Code 中開啟 dataconnect/connector/connector.yaml 檔案,即可找到預設設定。為便於在本程式碼研究室中查看程式碼產生情形,請將 connectorId 變更為 movies,套件則變更為 com.google.firebase.example.dataconnect.generated

connectorId: movies
generate:
  kotlinSdk:
    outputDir: ../../app/src/main/java
    package: com.google.firebase.example.dataconnect.generated

以下說明各個狀態代表的意義:

  • connectorId - 這個連接器的專屬名稱。
  • outputDir - 產生的 Data Connect SDK 會儲存在這個路徑中。這個路徑相對於包含 connector.yaml 檔案的目錄。
  • package:在產生的 SDK 中使用的套件名稱。

啟動 Firebase 模擬器

在 VS Code 中,按一下「Start emulators」按鈕。

93fb67962e96a7cb.png

您應該會在整合式終端機中看到模擬器啟動畫面。如果啟動正確,您應該會看到類似以下的輸出內容:

8504ae0080923823.png

設定 Android 應用程式以使用本機模擬器

  1. 開啟 Android Studio。
  2. 在 Android Studio 的歡迎畫面中,按一下「Open」按鈕,然後選取 codelab-dataconnect-android 目錄。等待 Gradle 同步處理。
  3. Gradle 同步處理完成後,請開啟 app/src/main/java/com/google/firebase/example/dataconnect/MainActivity.kt 檔案並呼叫 useEmulator()
import com.google.firebase.example.dataconnect.generated.MoviesConnector
import com.google.firebase.example.dataconnect.generated.instance

class MainActivity : ComponentActivity() {
  ...

  // Initialize Firebase Data Connect
  MoviesConnector.instance.dataConnect.useEmulator("10.0.2.2", 9399)

  ...
}

4. 定義結構定義並預先填入資料庫

在本節中,您將在結構定義中定義電影應用程式中關鍵實體之間的關係。MovieUserReview 等實體會對應至資料庫資料表,並使用 Firebase Data Connect 和 GraphQL 結構定義指令建立關聯。

核心實體和關係

Movie 類型會保留標題、類型和標記等重要詳細資料,應用程式會用於搜尋和電影設定檔。User 類型會追蹤使用者互動,例如評論和收藏。Review 可讓使用者觀看電影,並顯示使用者提供的評分和意見回饋。

使用者資料表

「使用者類型」定義了使用者實體,也就是透過留下評論或將電影設為喜愛項目,與電影互動的使用者。

在 VS Code 中開啟 dataconnect/schema/schema.gql 檔案,並取消註解 (或新增) User 資料表定義:

# Users
# Suppose 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)")
  # The following are generated by the user: User! field in the Review table
  # reviews_on_user 
  # movies_via_Review
}

電影表

電影類型定義了電影實體的主要結構,包括片名、類型、發行年份和評分等欄位。

在 VS Code 中開啟 dataconnect/schema/schema.gql 檔案,並取消註解 (或新增) Movie 資料表定義:

# Movies
type Movie @table {
  # The below parameter values are generated by default with @table, and can be edited manually.
  # implies directive `@col(name: "movie_id")`, generating a column name
  id: UUID! @default(expr: "uuidV4()")
  title: String!
  imageUrl: String!
  genre: String
}

MovieMetadata 資料表

MovieMetadata 類型會與 Movie 類型建立一對一關係。其中包含電影導演等其他資料。

在 VS Code 中開啟 dataconnect/schema/schema.gql 檔案,並取消註解 (或新增) MovieMetadata 資料表定義:

# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata @table {
  # @unique indicates a 1-1 relationship
  movie: Movie! @unique 
  # movieId: UUID <- this is created by the above reference
  rating: Float
  releaseYear: Int
  description: String
}

審查表

「Review」類型代表評論實體,並以多對多關係連結「User」和「Movie」類型 (一個使用者可以留下多則評論,每部電影也可能有許多評論)。

在 VS Code 中開啟 dataconnect/schema/schema.gql 檔案,並取消註解 (或新增) Review 資料表定義:

# Reviews
type Review @table(name: "Reviews", key: ["movie", "user"]) {
  id: UUID! @default(expr: "uuidV4()")
  user: User!
  movie: Movie!
  rating: Int
  reviewText: String
  reviewDate: Date! @default(expr: "request.time")
}

自動產生的欄位和預設值

這個結構定義會使用 @default(expr: "uuidV4()") 等運算式,自動產生不重複的 ID 和時間戳記。舉例來說,建立新記錄時,Movie 和 Review 類型的 id 欄位會自動填入 UUID。

插入模擬資料

定義好結構定義後,您現在可以預先在資料庫中填入模擬資料進行測試。

  1. 在 VS Code 中開啟 dataconnect/moviedata_insert.gql。確認 Firebase Data Connect 擴充功能中的模擬器是否正在執行。
  2. 檔案頂端應該會顯示「Run (local)」按鈕。按一下這個按鈕,即可將模擬電影資料插入資料庫。

b070f025e573ab9b.png

  1. 查看資料連結執行終端,確認資料是否已成功新增。

e2058cb4db857058.png

資料就緒後,請繼續進行下一個步驟,瞭解如何在 Data Connect 中建立查詢。

5. 建立查詢來列出電影

首先,請建立查詢來列出電影。您將為每部電影擷取 ID、標題、imageUrl 和類型。

定義查詢

在 VS Code 中開啟 dataconnect/connector/queries.gql 檔案,然後取消註解 (或新增) ListMovies 查詢:

query ListMovies @auth(level: PUBLIC) {
  movies {
    id
    title
    imageUrl
    genre
  }
}

如要測試新查詢,請按一下「Run (local)」(執行本機) 按鈕,對本機資料庫執行查詢。資料庫中的電影清單應顯示在 Data Connect 執行終端的「結果」部分下方。

822bf32321df4716.png

從 Android 應用程式呼叫

您已在 Data Connect Emulator 中測試查詢,現在可以將查詢新增至應用程式。

在 Android Studio 中開啟 app/src/main/java/com/google/firebase/example/dataconnect/MoviesScreen.kt 檔案,然後加入下列程式碼,以格狀格式顯示電影清單:

import com.google.firebase.example.dataconnect.generated.ListMoviesQuery
import com.google.firebase.example.dataconnect.generated.MoviesConnector
import com.google.firebase.example.dataconnect.generated.execute
import com.google.firebase.example.dataconnect.generated.instance

@Composable
fun MoviesScreen(
    onMovieClicked: (id: String) -> Unit
) {
    var movies by remember { mutableStateOf(emptyList<ListMoviesQuery.Data.MoviesItem>()) }
    LaunchedEffect(Unit) {
        // Queries need to be executed in a coroutine context
        try {
          movies = MoviesConnector.instance.listMovies.execute().data.movies
        } catch (e: Exception) {
          // Will be done at a later step
        }
    }
    LazyVerticalGrid(GridCells.Adaptive(150.dp)) {
        items(movies) { movie ->
            MovieCard(
                movieId = movie.id.toString(),
                movieTitle = movie.title,
                movieImageUrl = movie.imageUrl,
                movieGenre = movie.genre,
                onMovieClicked = {
                    onMovieClicked(movie.id.toString())
                }
            )
        }
    }
}

執行應用程式

在 Android Studio 中,按一下「Run」按鈕,在 Android 模擬器中啟動應用程式。

應用程式啟動後,您會看到類似下圖的畫面:

ddc52cd46f923cf1.png

6. 建立電影詳細資料查詢

應用程式現在可以列出電影,讓我們建立查詢,顯示每部電影的詳細資料。

定義查詢

在 VS Code 中開啟 dataconnect/connector/queries.gql 檔案,然後取消註解 (或新增) GetMovieById 查詢:

# Get movie by id
query GetMovieById($id: UUID!) @auth(level: PUBLIC) {
  movie(id: $id) {
    id
    title
    imageUrl
    genre
    metadata: movieMetadata_on_movie {
      rating
      releaseYear
      description
    }
    reviews: reviews_on_movie {
      id
      reviewText
      reviewDate
      rating
      user {
        id
        username
      }
    }
  }
}

從 Android 應用程式呼叫

在 Android Studio 中開啟 app/src/main/java/com/google/firebase/example/dataconnect/MovieDetailScreen.kt 檔案,然後加入下列程式碼:

importcom.google.firebase.example.dataconnect.generated.GetMovieByIdQuery
importcom.google.firebase.example.dataconnect.generated.MoviesConnector
importcom.google.firebase.example.dataconnect.generated.execute
importcom.google.firebase.example.dataconnect.generated.instance

@Composable
fun MovieDetailScreen(
    movieId: String
) {
    var movie by remember { mutableStateOf<GetMovieByIdQuery.Data.Movie?>(null) }
    LaunchedEffect(Unit) {
        movie = MoviesConnector.instance.getMovieById.execute(
            UUID.fromString(movieId)
        ).data.movie
    }
    if (movie == null) {
        LoadingScreen()
    } else {
        MovieDetails(
            movieTitle = movie!!.title,
            movieImageUrl = movie!!.imageUrl,
            movieGenre = movie!!.genre,
            movieRating = movie!!.metadata?.rating,
            movieReleaseYear = movie!!.metadata?.releaseYear,
            movieDescription = movie!!.metadata?.description,
        )
    }
}

執行應用程式

在 Android Studio 中,按一下「Run」按鈕,在 Android 模擬器中啟動應用程式。

7. 建立用於插入使用者的異動

應用程式現在可以顯示資料,因此您可以透過應用程式新增資料。為了確保安全性,請使用 Firebase 驗證功能。

為了配合本程式碼研究室的目的,應用程式會使用匿名驗證功能讓使用者登入,但為了讓應用程式更安全,建議您使用其他驗證方法,例如電子郵件/密碼驗證或聯合識別資訊提供者。

定義變異

在 VS Code 中開啟 dataconnect/connector/mutations.gql 檔案,然後取消註解 (或新增) UpsertUser 查詢:

# Upsert (update or insert) a user's username based on their auth.uid
mutation UpsertUser($username: String!) @auth(level: USER) {
  user_upsert(
    data: {
      id_expr: "auth.uid"
      username: $username
    }
  )
}

從 Android 應用程式呼叫

在 Android Studio 中開啟 app/src/main/java/com/google/firebase/example/dataconnect/MainActivity.kt 檔案,然後呼叫變異:

import com.google.firebase.example.dataconnect.generated.execute

LaunchedEffect(Unit) {
  // If there's no user signed in, sign in an anonymous user
  if (firebaseAuth.currentUser == null) {
    firebaseAuth.signInAnonymously().await()
    val newUsername = getRandomUsername()
    MoviesConnector.instance.upsertUser.execute(newUsername)
  }
}

執行應用程式

在 Android Studio 中,按一下「Run」按鈕,在 Android Emulator 中啟動應用程式。

8. 恭喜!

恭喜,您已成功在 Android 應用程式中新增 Firebase Data Connect!

您現在已瞭解設定 Data Connect、建立查詢和變異式,以及處理使用者驗證所需的重要步驟。

後續步驟

選用:部署至正式環境

目前這個應用程式只使用 Firebase 模擬器。如要瞭解如何將此應用程式部署至實際的 Firebase 專案,請繼續進行下一個步驟。

9. (選用) 部署應用程式

到目前為止,這個應用程式完全在本機執行,所有資料都包含在 Firebase 模擬器套件中。在本節中,您將瞭解如何設定 Firebase 專案,讓這個應用程式能在正式環境中運作。

啟用 Firebase 驗證

在 Firebase 控制台中,前往「驗證」部分,然後按一下「開始使用」。前往「登入方式」分頁,然後從提供者中選取「匿名登入」選項。

啟用匿名登入方法,然後按一下「儲存」。

部署 Firebase Data Connect 結構定義

重要事項:如果這是您第一次在專案中部署結構定義,這個程序會建立 Cloud SQL PostgreSQL 執行個體,這可能需要 15 分鐘的時間。您必須先準備好 Cloud SQL 執行個體並整合 Firebase Data Connect,才能進行部署。

  1. 在 Firebase Data Connect VS Code 擴充功能 UI 中,按一下「部署至正式環境」
  2. 您可能需要檢查結構定義變更,並核准可能會造成破壞性的修改。系統會提示你:
    • 使用 firebase dataconnect:sql:diff 查看結構定義變更
    • 滿意變更內容後,請使用 firebase dataconnect:sql:migrate 啟動的流程套用變更

您的 PostgreSQL 適用 Cloud SQL 執行個體會更新為最終部署的結構定義和資料。您可以在 Firebase 主控台中監控狀態。

您現在可以按一下 Firebase Data Connect 面板中的「Run (Production)」(執行 (實際工作環境)」,就像使用本機模擬器一樣,將資料新增至實際工作環境。