🔥

FireStoreへのSpringBootでの接続方法(Emulator使用)

2023/12/01に公開

概要・構築環境

サーバークライアントライブラリは以下のようにある(他にもオープンソースのものもあり)

  • FireBase Admin SDK
  • Google Cloud クライアントライブラリ

https://firebase.google.com/docs/firestore/client/libraries?hl=ja

最初にfirebaseのemulatorの設定から解説する

firebaseのemulatorの概要についてはここを参照
https://firebase.google.com/docs/emulator-suite?hl=ja

その後、SpringBootアプリを用いた接続方法について解説する

SpringBootはここのリンクからプロジェクトの雛形を作成可能

https://start.spring.io/

なお環境は以下の通り

開発環境 Intelli j community version
OS M1 Mac Monterey
言語 Java 11

Firebase emulatorの設定

Dockerの設定

今回はdockerを使用してfirestoreEmulatorを起動する

docker fileは以下のように設定する

FROM ubuntu:20.04

RUN apt update -y
RUN apt-get upgrade -y
RUN apt install -y curl

RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get install -y nodejs
RUN apt install -y openjdk-11-jdk

RUN npm install -g firebase-tools

docker-compose.ymlファイルは以下のよう

firebase:
    build: ./firebase
    image: firebase_emulator
    container_name: firebase_emulator
    environment:
      - JAVA_TOOL_OPTIONS="-Xmx4g"
    working_dir: /opt/firebase
    volumes:
      - ./firebase/config/firebase.json:/opt/firebase/firebase.json
      - ./firebase/bin/:/root/.cache:cached
      - ./firebase/config/:/root/.config:cached
    ports:
      - 8080:8080 # Cloud Firestore
      - 4000:4000 # Emulator Suite UI
    tty: true

Emulatorのセットアップ

準備ができたらdocker最初にログインをする

--no-localhostがないその後のブラウザのログイン画面でlocalhostに飛んでしまいエラーになるので注意

docker-compose run --rm firebase firebase login --no-localhost

その後使用しているユーザー等をを入力しログイン

その後このマンドでfireStoreプロジェクトのinitializeを行う

docker-compose run --rm firebase firebase init

巡に従っていけばOkay、spaceで選ばないとエラーになるのでそこだけ注意

https://qiita.com/mh4gf/items/4785b7fce4f7c78159fe

setUpがすんだ状態でlocalhost:4000にアクセスするとUIが表示できる

そのほか注意点

docker-compose run --rm firebase firebase use

で表示されるactiveProject名が、次に設定するアプリの環境変数と名前がマッチしていないとアクセスできないため注意が必要

(aliasで別の名前を指定すると、同じprojectIDを使用していてもアクセスできないことを確認)

active projectを指定したい場合は上記のコマンドの後にprojectIdを指定してあげればOk

アプリの設定

build.gradleへのdependenciesの追加

SpringBootの基本的な書き方、プロジェクトの作成方法に関しては省略する

プロジェクトを立ち上げたら

今回はgradelを使用するのでbuild.gradledependencyを追加する

以下の二つがあればOK

implementation 'com.google.firebase:firebase-admin:9.1.1'
implementation 'com.google.cloud:google-cloud-firestore:3.8.1'

最新Versionはここで確認できる

https://mvnrepository.com/artifact/com.google.cloud/google-cloud-firestore

https://firebase.google.com/support/release-notes/admin/java

環境変数の追加

Inttelijを使用しているため、debug configuraltionに以下の環境変数を設定する。これによりemulatorへのアクセスが可能となる

GCLOUD_PROJECT="test-project";FIRESTORE_EMULATOR_HOST=localhost:8080

初期化

まず初めに初期化を行う必要がある。

こちらを参考に作成したcredentialファイルを使用する必要がある

https://loooooovingyuki.medium.com/firestoreのデータをローカルから操作する方法-659b1cfb987b

InputStream serviceAccount = new FileInputStream("/credentialFilePash/credential.json");
GoogleCredentials credentials = GoogleCredentials.fromStream(serviceAccount);
FirebaseOptions options = new FirebaseOptions.Builder()
         .setCredentials(credentials)
         .build();
FirebaseApp.initializeApp(options);

FireStoreの宣言

Firestore db = FirestoreClient.getFirestore();

データの取得

ApiFuture<QuerySnapshot> query = db.collection("test").get();
QuerySnapshot querySnapshot = query.get();
List<QueryDocumentSnapshot> documents = querySnapshot.getDocuments();
for (QueryDocumentSnapshot document : documents) {
      System.out.println("test: " + document.getId());
 }

データのInsert・更新

データのInsert、同じIDのdocumentが存在している場合は更新される

DocumentReference docRef = db.collection("test").document("id1");
Map<String, Object> data = new HashMap<>();
data.put("name", "test");
data.put("id", "123");
ApiFuture<WriteResult> future = docRef.set(data);
System.out.printl("Update time : " + future.get().getUpdateTime());

データの削除

DocumentReference docRef = db.collection("test2").document("id2");
ApiFuture<WriteResult> writeResult = docRef
.delete();
System.out.println("Firestore: Update time : " + writeResult.get().getUpdateTime());

Batchによる書き込み

batchによるトランザクションをもった書き込みの上限は500document

以下のように実装できる

//transaction start
WriteBatch batch = db.batch();

DocumentReference nycRef = db.collection("test").document("id1");
Map<String, Object> data = new HashMap<>();
data.put("name", "test");
data.put("id", "123");

//データInsert,Update
batch.set(nycRef,dataBatch);

//コミット、トランザクション終了
ApiFuture<List<WriteResult>> commit = batch.commit();

for (WriteResult result : commit.get()) {
   System.out.println("Update time : " + result.getUpdateTime());
 }

参考

Java admin sdk

https://github.com/firebase/firebase-admin-java

FireStoreのデータ取得、削除、更新
https://firebase.google.com/docs/firestore/quickstart?hl=ja

トランザクションによる書き込み
https://firebase.google.com/docs/firestore/manage-data/transactions?hl=ja#java_1

トランザクション使用時のリミット
https://firebase.google.com/docs/firestore/quotas?hl=ja#writes_and_transactions

リンクリスト
https://qiita.com/niwasawa/items/d84a617f1f949c7fe9e7

Discussion