在本機開始使用 Firebase Data Connect

在本快速入門課程中,您將瞭解如何在應用程式中建構 Firebase Data Connect,而不需要設定正式 SQL 執行個體。您將學會以下內容:

  • Firebase Data Connect 新增至 Firebase 專案。
  • 設定開發環境,包括 Visual Studio Code 擴充功能,以便與本機執行個體搭配使用。
  • 接著,我們會說明如何:
    • 為電影應用程式建立結構定義
    • 定義應用程式中要使用的查詢和變異
    • 使用本機模擬器的範例資料測試查詢和異動
    • 產生強型別 SDK,並在應用程式中使用
    • 部署最終結構定義、查詢和資料至雲端 (選用,需要升級至 Blaze 方案)。

選擇本機開發流程

Data Connect 提供兩種安裝開發工具及在本機作業的方式。

事前準備

如要使用本快速入門導覽課程,您需要:

設定開發環境

  1. 為本機專案建立新目錄。
  2. 在您建立的新目錄中執行下列指令。

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

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

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

設定專案目錄

如要設定本機專案,請初始化專案目錄。在 IDE 視窗的左側面板中,按一下 Firebase 圖示,開啟 Data Connect VS Code 擴充功能 UI:

  1. 點選「使用 Google 帳戶登入」按鈕。
  2. 按一下「連結 Firebase 專案」按鈕,然後選取先前在控制台中建立的專案。
  3. 按一下「Run firebase init」按鈕。
  4. 按一下「Start emulators」按鈕。

建立結構定義

在 Firebase 專案目錄的 /dataconnect/schema/schema.gql 檔案中,開始定義關於電影的 GraphQL 結構定義。

電影

Data Connect 中,GraphQL 欄位會對應至欄。電影有 idtitleimageUrlgenreData Connect 可識別原始資料類型:StringUUID

複製下列程式碼片段,或取消註解檔案中的對應行。

# By default, a UUID id key will be created by default as primary key.
# If you want to specify a primary key, say title, which you can do through
# the @table(key: "title") directive
type Movie @table {
  id: UUID! @default(expr: "uuidV4()")
  title: String!
  imageUrl: String!
  genre: String
}

MovieMetadata

複製下列程式碼片段,或取消註解檔案中的對應行。

# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata @table {
  # This time, we omit adding a primary key because
  # you can rely on Data Connect to manage it.

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

請注意,movie 欄位會對應至 Movie 類型。Data Connect 瞭解這是 MovieMovieMetadata 之間的關係,並會為您管理這項關係。

進一步瞭解說明文件中的 Data Connect 結構定義

在表格中新增資料

在 IDE 編輯器面板中,您會在 /dataconnect/schema/schema.gql 的 GraphQL 類型上方看到 CodeLens 按鈕。您可以使用「Add data」和「Run (Local)」按鈕,將資料新增至本機資料庫。

如要在 MovieMovieMetadata 表格中新增記錄,請按照下列步驟操作:

  1. schema.gql 中,按一下 Movie 類型宣告上方的「Add data」按鈕。
    Firebase Data Connect 的 CodeLens 新增資料按鈕
  2. 在產生的 Movie_insert.gql 檔案中,為三個欄位硬式編碼資料。
  3. 按一下「Run (Local)」按鈕。
    Firebase Data Connect 的 CodeLens 執行按鈕
  4. 重複上述步驟,在 MovieMetadata 資料表中新增記錄,並在 movieId 欄位中提供電影的 id,如產生的 MovieMetadata_insert 變異顯示。

如要快速驗證資料是否已新增,請按照下列步驟操作:

  1. 回到 schema.gql,按一下 Movie 型別宣告上方的「Read data」按鈕。
  2. 在產生的 Movie_read.gql 檔案中,按一下「Run (Local)」按鈕執行查詢。

進一步瞭解說明文件中的 Data Connect 變異體

定義查詢

接下來是精彩的部分:讓我們在應用程式中定義所需的查詢。開發人員通常習慣編寫 SQL 查詢,而非 GraphQL 查詢,因此一開始可能會覺得有點不同。

不過,GraphQL 比原始 SQL 更精簡,且具有類型安全性。我們的 VS Code 擴充功能可讓開發體驗更輕鬆。

開始編輯 /dataconnect/connector/queries.gql 檔案。如要取得所有電影,請使用類似以下的查詢。

# File `/dataconnect/connector/queries.gql`

# @auth() directives control who can call each operation.
# Anyone should be able to list all movies, so the auth level is set to PUBLIC
query ListMovies @auth(level: PUBLIC) {
  movies {
    id
    title
    imageUrl
    genre
  }
}

使用附近的 CodeLens 按鈕執行查詢。

這項功能的一大優點,就是可以將資料庫的關係視為圖表。由於 MovieMetadata 記錄含有參照電影的 movie 欄位,您可以巢狀進入該欄位,並取得電影資訊。請嘗試將產生的類型 movieMetadata_on_movie 新增至 ListMovies 查詢。

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

進一步瞭解說明文件中的 Data Connect 查詢

產生 SDK 並在應用程式中使用

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

  1. 按一下「Add SDK to app」按鈕。
  2. 在隨即顯示的對話方塊中,選取包含應用程式程式碼的目錄。系統會產生 Data Connect SDK 程式碼並儲存在該目錄中。

  3. 選取應用程式平台後,SDK 程式碼會立即在所選目錄中產生。

使用 SDK 從應用程式呼叫查詢

您可以使用 Data Connect 產生的 SDK,對 ListMovies 查詢執行呼叫。接著,您可以使用 Data Connect 模擬器在本機上執行這項查詢。

網頁版

  1. 將 Firebase 新增至網頁應用程式。
  2. 在 React 應用程式的主檔案中:

    • 匯入您產生的 SDK
    • 檢測應用程式,以連線至 Data Connect 模擬器
    • 呼叫 Data Connect 方法。

    您可以複製下列程式碼片段,並將其做為獨立應用程式執行。

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    
    import { connectDataConnectEmulator } from 'firebase/data-connect';
    
    // Generated queries.
    // Update as needed with the path to your generated SDK.
    import { listMovies, ListMoviesData } from '@movie-app/movies';
    
    const dataConnect = getDataConnect(connectorConfig);
    connectDataConnectEmulator(dataConnect, 'localhost', 9399);
    
    function App() {
      const [movies, setMovies] = useState<ListMoviesData['movies']>([]);
      useEffect(() => {
        listMovies.then(res => setMovies(res.data));
      }, []);
      return (
        movies.map(movie => <h1>{movie.title}</h1>);
      );
    }
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(<App />);    
    

Swift

  1. 將 Firebase 新增至 iOS 應用程式。
  2. 如要使用產生的 SDK,請在 Xcode 中將其設為依附元件。

    在 Xcode 頂端導覽列中,依序選取「File」>「Add Package Dependencies」>「Add Local」,然後選擇包含產生 Package.swift 的資料夾。

  3. 在應用程式的主委派作業中:

    • 匯入您產生的 SDK
    • 檢測應用程式,以連線至 Data Connect 模擬器
    • 呼叫 Data Connect 方法。

    您可以複製下列程式碼片段,並將其做為獨立應用程式執行。

    import SwiftUI
    
    import FirebaseDataConnect
    // Generated queries.
    // Update as needed with the package name of your generated SDK.
    import <CONNECTOR-PACKAGE-NAME>
    
    let connector = DataConnect.moviesConnector
    
    // Connect to the emulator on "127.0.0.1:9399"
    connector.useEmulator()
    
    // (alternatively) if you're running your emulator on non-default port:
    // connector.useEmulator(port: 9999)
    
    struct ListMovieView: View {
    @StateObject private var queryRef = connector.listMovies.ref()
    
        var body: some View {
            VStack {
                Button {
                    Task {
                        do {
                            try await refresh()
                        } catch {
                            print("Failed to refresh: \(error)")
                        }
                    }
                } label: {
                    Text("Refresh")
                }
    
                // use the query results in a view
                ForEach(queryRef.data?.movies ?? [], id: \.self.id) { movie in
                        Text(movie.title)
                    }
                }
        }
        @MainActor
        func refresh() async throws {
            _ = try await queryRef.execute()
        }
    
        struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ListMovieView()
        }
    }
    

Kotlin Android

  1. 將 Firebase 新增至 Android 應用程式。
  2. 如要使用產生的 SDK,請將 Data Connect 設為 Gradle 中的依附元件。

    更新 app/build.gradle.kts 中的 pluginsdependencies

    plugins {
      // Use whichever versions of these dependencies suit your application.
      // The versions shown here were the latest as of December 03, 2024.
      // Note, however, that the version of kotlin("plugin.serialization") must,
      // in general, match the version of kotlin("android").
      id("com.android.application") version "8.7.3"
      id("com.google.gms.google-services") version "4.4.2"
      val kotlinVersion = "2.1.0"
      kotlin("android") version kotlinVersion
      kotlin("plugin.serialization") version kotlinVersion
    }
    
    dependencies {
      // Use whichever versions of these dependencies suit your application.
      // The versions shown here were the latest versions as of December 03, 2024.
      implementation("com.google.firebase:firebase-dataconnect:16.0.0-beta03")
      implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
      implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3")
    
      // These dependencies are not strictly required, but will very likely be used
      // when writing modern Android applications.
      implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
      implementation("androidx.appcompat:appcompat:1.7.0")
      implementation("androidx.activity:activity-ktx:1.9.3")
      implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7")
      implementation("com.google.android.material:material:1.12.0")
    }
    
  3. 在應用程式的主活動中:

    • 匯入您產生的 SDK
    • 檢測應用程式,以連線至 Data Connect 模擬器
    • 呼叫 Data Connect 方法。

    您可以複製下列程式碼片段,並將其做為獨立應用程式執行。

    import android.os.Bundle
    import android.widget.TextView
    import androidx.appcompat.app.AppCompatActivity
    import androidx.lifecycle.Lifecycle
    import androidx.lifecycle.lifecycleScope
    import androidx.lifecycle.repeatOnLifecycle
    import kotlinx.coroutines.launch
    
    
    private val connector = com.myapplication.MoviesConnector.instance
      .apply {
        // Connect to the emulator on "10.0.2.2:9399" (default port)
        dataConnect.useEmulator()
    
        // (alternatively) if you're running your emulator on non-default port:
        // dataConnect.useEmulator(port = 9999)
      }
    
    
    class MainActivity : AppCompatActivity() {
    
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val textView: TextView = findViewById(R.id.text_view)
    
        lifecycleScope.launch {
          lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
            
            val result = connector.listMovies.runCatching { execute { } }
            
            val newTextViewText = result.fold(
              onSuccess = {
                val titles = it.data.movies.map { it.title }
                "${titles.size} movies: " + titles.joinToString(", ")
              },
              onFailure = { "ERROR: ${it.message}" }
            )
            textView.text = newTextViewText
          }
        }
      }
    }
    

Flutter

  1. 將 Firebase 新增至 Flutter 應用程式。
  2. 安裝 FlutterFire CLI dart pub global activate flutterfire_cli
  3. 執行 flutterfire configure
  4. 在應用程式的主函式中:

    • 匯入您產生的 SDK
    • 檢測應用程式,以連線至 Data Connect 模擬器
    • 呼叫 Data Connect 方法。

    您可以複製下列程式碼片段,並將其做為獨立應用程式執行。

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart';

// Generated queries.
// Update as needed with the path to your generated SDK

import 'movies_connector/movies.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  
  MoviesConnector.instance.dataConnect
      .useDataConnectEmulator(Uri.base.host, 443, isSecure: true);
  
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: Column(children: [
      ConstrainedBox(
        constraints: const BoxConstraints(maxHeight: 200),
        child: FutureBuilder(
            future: MoviesConnector.instance.listMovies().execute(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                return ListView.builder(
                  scrollDirection: Axis.vertical,
                  itemBuilder: (context, index) => Card(
                      child: Text(
                    snapshot.data!.data.movies[index].title,
                  )),
                  itemCount: snapshot.data!.data.movies.length,
                );
              }
              return const CircularProgressIndicator();
            }),
      )
    ])));
  }
}

將結構定義和查詢部署至實際工作環境

在應用程式上完成本機設定後,您可以將結構定義、資料和查詢部署到雲端。您需要 Blaze 方案專案才能設定 Cloud SQL 執行個體。

  1. 前往 Firebase 控制台的 Data Connect 專區,建立 Cloud SQL 免付費試用版。

  2. 在 IDE 整合的 Terminal 中,執行 firebase init dataconnect,然後選取您剛在控制台中建立的區域/服務 ID

  3. 當系統提示「File dataconnect/dataconnect.yaml already exists, Overwrite?」時,請選取「Y」

  4. 在 IDE 視窗的 VS Code 擴充功能 UI 中,按一下「Deploy to production」按鈕。

  5. 部署完成後,請前往 Firebase 控制台,確認結構定義、作業和資料已上傳至雲端。您應該可以查看結構定義,並在控制台中執行作業。系統會更新 PostgreSQL 適用的 Cloud SQL 執行個體,並使用最終部署產生的結構定義和資料。

後續步驟

查看已部署的專案,並探索更多工具:

  • Firebase 控制台中,將資料新增至資料庫、檢查及修改結構定義,並監控 Data Connect 服務。

如需更多資訊,請參閱說明文件。舉例來說,您已完成快速入門導覽課程: