Firebase Data Connect を使用してビルドする(Android)

1. 概要

ddc52cd46f923cf1.png

この Codelab では、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. ボタンをクリックして新しいプロジェクトを作成し、プロジェクト名(例: Movie Review)を入力します。
  3. [続行] をクリックします。
  4. Firebase の利用規約が表示されたら、内容を読み、同意して [続行] をクリックします。
  5. (省略可)Firebase コンソールで AI アシスタンス(「Gemini in Firebase」)を有効にします。
  6. この Codelab では Google アナリティクスは必要ないため、Google アナリティクスのオプションをオフに切り替えます
  7. [プロジェクトを作成] をクリックし、プロジェクトのプロビジョニングが完了するまで待ってから、[続行] をクリックします。

コードをダウンロードする

次のコマンドを実行して、この Codelab のサンプルコードのクローンを作成します。これにより、マシンに 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 には、スキーマの管理、アプリケーションで使用するクエリとミューテーションの定義、厳密に型指定された SDK の生成に役立つツール(事前バンドルされた VS Code 拡張機能など)が用意されています。

スクリプトを実行すると、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 ファイルを開くと、デフォルトの構成が表示されます。この Codelab でコード生成を視覚化しやすくするために、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 で、[エミュレータを開始] ボタンをクリックします。

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 はユーザーを映画に結び付け、アプリでユーザーが作成した評価やフィードバックを表示できるようにします。

ユーザー テーブル

User タイプは、レビューを残したり、映画をお気に入りに追加したりして映画を操作するユーザー エンティティを定義します。

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
}

映画の表

Movie 型は、タイトル、ジャンル、リリース年、評価などのフィールドを含む、映画エンティティのメイン構造を定義します。

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 型と 1 対 1 の関係を確立します。映画の監督などの追加データが含まれます。

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 タイプを多対多の関係でリンクします(1 人のユーザーが複数のレビューを残すことができ、各映画には複数のレビューが付けられます)。

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. Data Connect Execution ターミナルで、データが正常に追加されたことを確認します。

e2058cb4db857058.png

データが配置されたら、次のステップに進んで、Data Connect でクエリを作成する方法を学習します。

5. 映画を一覧表示するクエリを作成する

まず、映画を一覧表示するクエリを作成します。映画ごとに、ID、タイトル、imageUrl、ジャンルを取得します。

クエリを定義する

VS Code で dataconnect/connector/queries.gql ファイルを開き、ListMovies クエリのコメントを解除(または追加)します。

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

新しいクエリをテストするには、[実行(ローカル)] ボタンをクリックして、ローカル データベースに対してクエリを実行します。データベースの映画のリストが、Data Connect Execution ターミナルの [result] セクションに表示されます。

822bf32321df4716.png

Android アプリから呼び出す

Data Connect エミュレータでクエリをテストしたので、アプリに追加します。

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 で [実行] ボタンをクリックして、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 で [実行] ボタンをクリックして、Android エミュレータでアプリを起動します。

7. ユーザーを挿入するミューテーションを作成する

アプリでデータを表示できるようになったので、アプリから新しいデータを追加します。安全にデータを追加するには、Firebase Authentication を使用する必要があります。

この Codelab では、アプリは匿名認証を使用してユーザーをログインさせますが、より安全なアプリにするには、メール/パスワード認証やフェデレーション ID プロバイダなどの別の認証方法を使用することを検討してください。

ミューテーションを定義する

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 で [実行] ボタンをクリックして、Android エミュレータでアプリを起動します。

8. 完了

Firebase Data Connect を Android アプリに正常に追加できました。

これで、Data Connect の設定、クエリとミューテーションの作成、ユーザー認証の処理に必要な主な手順を学習できました。

次のステップ

省略可: 本番環境にデプロイする

これまでのところ、このアプリは Firebase エミュレータのみを使用しています。このアプリを実際の Firebase プロジェクトにデプロイする方法については、次のステップに進んでください。

9. (省略可)アプリをデプロイする

これまでのところ、このアプリは完全にローカルで、すべてのデータが Firebase Emulator Suite に含まれています。このセクションでは、このアプリが本番環境で動作するように Firebase プロジェクトを構成する方法について説明します。

Firebase Authentication を有効にする

Firebase コンソールで [認証] セクションに移動し、[始める] をクリックします。[ログイン方法] タブに移動し、プロバイダから [匿名ログイン] オプションを選択します。

匿名ログイン方法を有効にして、[保存] をクリックします。

Firebase Data Connect スキーマをデプロイする

重要: プロジェクトでスキーマを初めてデプロイする場合は、このプロセスで Cloud SQL PostgreSQL インスタンスが作成されます。これには 15 分ほどかかることがあります。Cloud SQL インスタンスが準備され、Firebase Data Connect と統合されるまで、デプロイすることはできません。

  1. Firebase Data Connect VS Code 拡張機能の UI で、[Deploy to production] をクリックします。
  2. スキーマの変更を確認し、破壊的な変更を承認する必要がある場合があります。次の操作を求められます。
    • firebase dataconnect:sql:diff を使用してスキーマの変更を確認する
    • 変更に問題がなければ、firebase dataconnect:sql:migrate で開始されたフローを使用して変更を適用します。

Cloud SQL for PostgreSQL インスタンスは、最終的にデプロイされたスキーマとデータで更新されます。ステータスは Firebase コンソールでモニタリングできます。

ローカル エミュレータの場合と同様に、Firebase Data Connect パネルで [Run (Production)] をクリックして、本番環境にデータを追加できるようになりました。