Firebase Data Connect を使ってみる

このクイックスタートでは、Firebase Data Connect を使用してウェブアプリとモバイルアプリを PostgreSQL データベースに接続する方法について説明します。次のことを行います。

  • VS Code と Firebase CLI を使用して、ローカルの Firebase Data Connect プロジェクト ディレクトリを設定します。
  • 自然言語でアプリのアイデアに基づいて Data Connect スキーマ、クエリ、ミューテーションを生成します。
  • アプリで厳密に型指定された SDK を使用して、Data Connect クエリとミューテーションを実行します。
  • Cloud SQL for PostgreSQL インスタンス、Data Connect スキーマ、クエリ、ミューテーションをプロビジョニングします(Blaze プランが必要です)。

ローカル プロジェクト ディレクトリを設定する

Data Connect のローカル開発ツールは、次の 2 つの方法でインストールできます。

  1. プロジェクト ディレクトリで、次のコマンドを実行します。

    このスクリプトは、Firebase CLI と Data Connect VS Code 拡張機能をインストールし、firebase init dataconnect を使用してプロジェクトを設定する手順を説明します。VS Code デスクトップがインストールされていない場合、スクリプトはブラウザで開きます。

    curl -sL https://firebase.tools/init/dataconnect | editor=true bash
  2. Visual Studio Code の左側のパネルにある Firebase アイコンをクリックして、Data Connect VS Code 拡張機能の画面を開きます。

  3. [エミュレータを開始] をクリックして、ローカル PGlite データベースでエミュレータを実行します。

レビュー スキーマ

Firebase Data Connect は、GraphQL を使用してデータモデルを定義します。@table ディレクティブは、GraphQL 型を PostgreSQL テーブルにマッピングします。型のフィールドは PostgreSQL の列にマッピングされます。複合主キーを持つ結合テーブルを使用した多対多の関係など、他の @table 型を参照するフィールドを使用して、テーブル間の関係を定義できます。

デフォルトのセットアップでは、Data Connect スキーマ ファイルは dataconnect/schema/ ディレクトリにあります。映画テンプレート スキーマの 2 つのテーブルの例を次に示します。Gemini を使用してスキーマを生成した場合、スキーマが異なることがあります。

type Movie @table {
  # Every table has an implicit primary key field that looks something like:
  #  id: UUID! @default(expr: "uuidV4()")
  title: String!
  imageUrl: String!
  genre: String
}

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

Data Connect スキーマの詳細

クエリとミューテーションを作成する

Firebase Data Connect は、クエリとミューテーションに GraphQL を使用します。これらは .gql ファイルで定義し、アプリから名前で呼び出します。GraphQL 構文は、アプリに必要なデータを正確に取得するための、厳密に型指定された SDK と柔軟な API を提供します。

データベースにデータをシードする

エミュレータが実行されたら、初期データをシードできます。提供された dataconnect/seed_data.gql ファイルを使用することも、独自のミューテーションを作成することもできます。

VS Code の [Run (local)] Code Lens ボタンを使用して、ミューテーションを実行し、ローカルの PGlite データベースにデータを入力します。

Firebase Data Connect の CodeLens 実行ボタン

クエリとミューテーションを確認する

デフォルトの設定では、Data Connect のクエリとミューテーションは dataconnect/example/ ディレクトリにあります。

ネストされたクエリを使用すると、リレーショナル データに対して正確にクエリを実行できます。

query ListMovies @auth(level: PUBLIC, insecureReason: "Anyone can list all movies and their reviews.") {
  movies {
    title imageUrl genre
    reviews_on_movie {
      rating reviewDate
      user { username }
    }
  }
}

Data Connect を使用すると、Firebase Auth で安全なクエリとミューテーションを構築できます。

アプリのセキュリティを維持するため、ウェブアプリとモバイルアプリは @auth ディレクティブを使用して Data Connect クエリとミューテーションにのみアクセスできます。クエリとミューテーションは、{field}_expr: "auth.uid" などの式を使用して Firebase Auth UID に安全にアクセスできます。

mutation AddReview($movieId: UUID!, $rating: Int!, $reviewText: String!) @auth(level: USER) {
  review_upsert(
    data: {
      userId_expr: "auth.uid"
      movieId: $movieId
      rating: $rating
      reviewText: $reviewText
    }
  )
}

Data Connect クエリの詳細 Data Connect ミューテーションの詳細 Data Connect 認証の詳細

クエリとミューテーションを生成する

Data Connect を効果的に使用するために、GraphQL の専門家である必要はありません。自然言語の説明から Data Connect クエリとミューテーションを生成できます。

.gql ファイルで、# と入力してコメントを開始し、クエリまたはミューテーションを記述します。次に、[Generate/Refine Operation] Code Lens ボタンを使用して、GraphQL オペレーションを生成します。

Firebase Data Connect の CodeLens 生成ボタン

生成された SDK をアプリで使用する

firebase init dataconnect は、プロジェクト内のアプリ用に型安全性のある SDK を自動的に設定します。必要に応じて、VS Code 拡張機能の [アプリに SDK を追加] ボタンを使用するか、firebase init dataconnect:sdk を実行して、SDK を手動で追加できます。

Web

  1. ウェブアプリに Firebase を追加します。
  2. React アプリのメインファイルで、次のようにします。

    • 生成された SDK をインポートします。
    // Update as needed with the path to your generated SDK.
    import { listMovies, ListMoviesData } from '@dataconnect/generated';
    
    • アプリを計測可能にして Data Connect エミュレータに接続します。
    import { connectDataConnectEmulator } from 'firebase/data-connect';
    
    const dataConnect = getDataConnect(connectorConfig);
    connectDataConnectEmulator(dataConnect, 'localhost', 9399);
    
    • Data Connect メソッドを呼び出します。
    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. アプリのメイン デリゲートで:

    • Data Connect SDK と生成された SDK をインポートします。

      import FirebaseDataConnect
      // Generated queries.
      // Update as needed with the package name of your generated SDK.
      import <CONNECTOR-PACKAGE-NAME>
      
      let connector = DataConnect.moviesConnector
      
    • アプリを計測可能にして Data Connect エミュレータに接続します。

      // 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)
      
    • Data Connect メソッドを呼び出します。

      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 ?? []) { 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. Android アプリに Firebase を追加します。
  2. 生成された SDK を使用するには、Gradle で Data Connect を依存関係として構成します。

    app/build.gradle.ktspluginsdependencies を更新します。

    plugins {
      // Use whichever versions of these dependencies suit your application.
      // The versions shown here were the latest as of March 14, 2025.
      // Note, however, that the version of kotlin("plugin.serialization") must,
      // in general, match the version of kotlin("android").
      id("com.android.application") version "8.9.0"
      id("com.google.gms.google-services") version "4.4.2"
      val kotlinVersion = "2.1.10"
      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 March 14, 2025.
      implementation("com.google.firebase:firebase-dataconnect:16.0.0-beta04")
      implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1")
      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.10.1")
      implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7")
      implementation("com.google.android.material:material:1.12.0")
    }
    
  3. アプリのメイン アクティビティで、次の処理を行います。

    • 生成された SDK からコネクタ インスタンスを取得します。
    private val connector = com.myapplication.MoviesConnector.instance
    
    • アプリを計測可能にして Data Connect エミュレータに接続します。
    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)
      }
    
    • Data Connect メソッドを呼び出します。
    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. Flutter アプリに Firebase を追加します。
  2. flutterfire CLI dart pub global activate flutterfire_cli をインストールします。
  3. flutterfire configure を実行します。
  4. アプリのメイン関数で、次の操作を行います。

    • 生成された SDK をインポートします。
    // Generated queries.
    // Update as needed with the path to your generated SDK
    
    import 'movies_connector/movies.dart';
    
    • アプリを計測可能にして Data Connect エミュレータに接続します。
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp(
        options: DefaultFirebaseOptions.currentPlatform,
      );
      
      MoviesConnector.instance.dataConnect
          .useDataConnectEmulator(Uri.base.host, 443, isSecure: true);
      
      runApp(const MyApp());
    }
    
    • Data Connect メソッドを呼び出します。
    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();
                }),
          )
        ])));
      }
    }
    

本番環境にデプロイする

スキーマ、クエリ、ミューテーションを本番環境にデプロイするには:

  1. Firebase プロジェクトをアップグレードして Blaze プランを使用します。

  2. Data Connect VS Code 拡張機能で [Deploy to production] ボタンをクリックするか、ターミナルで次のコマンドを実行します。

    firebase deploy --only dataconnect
    

    デプロイ後、Firebase コンソールにアクセスして、スキーマを表示し、クエリとミューテーションを実行します。

dataconnect.yaml の詳細 Data Connect が Cloud SQL と連携する仕組みの詳細

次のステップ

クイックスタートが完了したので、次の手順に進みます。