🍣

【Firebase】Firestore Databaseでシーケンスを使いたい

2024/05/28に公開2

はじめに

Fletterを使用して画面実装をしている中で、複数の画像を一定の順番で表示したいというシチュエーションに遭遇しました。
普段SQLでDB操作している身としては、oracleとかのシーケンスみたいな概念を使って整理したいなと思ったのですが・・・。
調べると、Firestore Databaseにはシーケンスの概念がなさそうだったので、採番ルールを実装してみました。

こんな感じで画像を一定の順番で並べたい。

概要

結構原始的ですが、以下のように実装しました。

  1. 採番用のドキュメントを作成
  2. 新規採番用のメソッドを作成
  3. 連番を進めるためのメソッドを作成

1. 採番用のドキュメントを作成

採番用のドキュメントを作成します。
今回は、親として画像情報を保存しておくimagesというドキュメントと、採番用のドキュメントとして、image_branch_idを作成しました。

images

親のドキュメントでは、ユーザごとに画像情報を保存しています。
子のドキュメントである、image_branch_idで採番した連番(image_branch_id)をフィールドとして持たせています。

user_id name image_branch_id insert_date_time update_date_time
ユーザA test.png 1 2023年11月21日 12:17:28 2023年11月21日 12:17:28
ユーザA test2.png 2 2023年11月22日 14:23:34 2023年11月22日 14:23:34
ユーザA test3.png 3 2023年11月22日 14:43:20 2023年11月22日 14:43:20
ユーザA test4.png 4 2023年11月22日 15:09:10 2023年11月22日 15:09:10
ユーザB test.png 1 2024年5月22日 08:59:02 2024年5月22日 08:59:02

image_branch_id

ユーザごとに連番を持たせるようにしました。

user_id image_branchId insert_date_time update_date_time
ユーザA 1 2024年5月27日 17:23:36 2024年5月27日 17:23:36
ユーザB 4 2023年11月22日 15:09:10 2023年11月22日 15:09:10

2. 新規採番用のメソッドを作成

新しい連番を登録するためのメソッドを作成します。
今回はユーザ単位で連番を管理しているので、新規ユーザが新たに画像登録した際に、このメソッドを呼び出して、ドキュメントを追加していくことになります。

  /// 画像枝番を新規採番
  void _addImageBranchId(){
    final db = FirebaseFirestore.instance;

    final imageBranchId = <String, dynamic>{
      "user_id": userId,
      "image_branchId": 1,
      "insert_date_time": Timestamp.now(),
      "update_date_time": Timestamp.now(),
    };
    db.collection("image_branch_id").add(imageBranchId);
  }

3. 連番を進めるためのメソッドを作成

該当の連番を1つ進め、取得した連番を返戻します。
該当のユーザに紐づく連番を取得し、連番登録されていなければ新規登録、連番登録済みなら1つ進めて更新します。

  /// 画像ファイルの連番を進める
  Future<int> _getImageBranchId() async {
    final db = FirebaseFirestore.instance;

    // 該当のユーザの連番を取得
    final event = await db.collection("image_branch_id")
        .where('user_id', isEqualTo: userId).get();
    final docs = event.docs;
    final imageBranch = docs.map((docs) => 
        ImageBranchId.fromFirestore(docs)).toList();

    // 該当のユーザの連番が採番されていない場合は新規登録
    if(imageBranch.isEmpty){
      _addImageBranchId();
      return 1;
    }

    // 該当のユーザの連番を更新する
    _updateImageBranchId(imageBranch[0]);
    return imageBranch[0].imageBranchId + 1;
  }
  /// 画像枝番を進める
  void _updateImageBranchId(ImageBranchId entity){
    final db = FirebaseFirestore.instance;

    final imageBranchId = <String, dynamic>{
      "user_id": entity.userId,
      "image_branchId": entity.imageBranchId + 1,
      "update_date_time": Timestamp.now(),
    };
    
    db.collection("image_branch_id").doc(entity.id).update(imageBranchId);
  }

さいごに

後はimagesに新規で画像情報を登録する際に、採番した連番をimage_branchIdに登録します。
ここまで実装して、そもそもimagesに登録日を持たせているので、そのフィールドをソートして取得すれば済んだんじゃないかという考えに至りました。。。
今回はあまり意味がありませんでしたが、連番の実装ができたということで、今後使い方を考えながら、使いこなせたらいいかなと思います。

Discussion

JboyHashimotoJboyHashimoto

裁判とかは知らないですけど、タイムスタンプで僕は以前はやってましたね。それをwhere()使って、順番変えてましたね。

katoshikatoshi

コメントありがとうございます!
やっぱりそうですよね・・・。実装しきってから気づきました。。。