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

1. 概要

ddc52cd46f923cf1.png

この Codelab では、Firebase Data Connect を Cloud SQL データベースと統合して、映画レビューの Android アプリを作成します。次のことを学びます。

  • Firebase Data Connect の GraphQL スキーマを作成する
  • クエリとミューテーションを作成する
  • ユーザー認証を実装してデータを保護する

前提条件

  • Android Studio の最新バージョン
  • API レベル 23 以降を搭載した Android Emulator

学習内容

  • ローカル エミュレータを使用して Firebase Data Connect を設定する方法。
  • Data Connect と GraphQL を使用してデータスキーマを設計する方法。
  • 映画レビュー アプリのクエリとミューテーションを作成する方法。
  • Kotlin SDK を生成し、Android アプリで使用する方法。
  • (省略可)Data Connect サービスを本番環境にデプロイする方法。

2. サンプル プロジェクトをセットアップする

Firebase プロジェクトを作成する

  1. Google アカウントで Firebase コンソールにログインします。
  2. Firebase コンソールで、[プロジェクトを追加] をクリックします。
  3. Firebase プロジェクトの名前(「Movie Review」など)を入力し、[続行] をクリックします。
  4. Google アナリティクスを有効にするよう求められる場合があります。このコードラボでは、どちらを選択してもかまいません。
  5. 約 1 分後に Firebase プロジェクトの準備が整います。[続行] をクリックします。

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

次のコマンドを実行して、この 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 には、事前バンドルの 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 ファイルを開くと、デフォルトの構成が表示されます。この Codelab でコード生成を視覚化しやすいように、connectorId を movies に、package を 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
}

映画テーブル

Movie タイプは、title、genre、releaseYear、rating などのフィールドを含む、映画エンティティのメイン構造を定義します。

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、title、imageUrl、genre を取得します。

クエリを定義する

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

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

新しいクエリをテストするには、[実行(ローカル)] ボタンをクリックして、ローカル データベースに対してクエリを実行します。データベース内の映画のリストが、Data Connect 実行ターミナルの [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 で、[本番環境にデプロイ] をクリックします。
  2. スキーマの変更を確認し、破壊的な変更を承認する必要がある場合があります。次のいずれかを選択できます。
    • firebase dataconnect:sql:diff を使用してスキーマの変更を確認する
    • 変更に問題がなければ、firebase dataconnect:sql:migrate で開始したフローを使用して変更を適用します。

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

これで、ローカル エミュレータの場合と同様に、Firebase Data Connect パネルで [実行(本番環境)] をクリックして、本番環境にデータを追加できます。