質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

NoSQL

NoSQL(not only SQL)は、リレーショナルデータベース管理システムとは異なるデータベースシステムを指す言葉です。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

1回答

266閲覧

NoSQL(Firebase)に格納したデータの取得方法が分かりません(Flutter/Dart)

meex

総合スコア83

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

NoSQL

NoSQL(not only SQL)は、リレーショナルデータベース管理システムとは異なるデータベースシステムを指す言葉です。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

1クリップ

投稿2025/04/24 08:28

編集2025/04/25 00:49

実現したいこと

ある会社では従業員情報を下記のようなNoSQLのドキュメント指向データベースに保存している。
従業員情報は、従業員自身が社内ポータルサイトで検索・閲覧することができる。
社内ポータルサイトは、ログインID/PWの他に、部署名と役職名も入力した上でログインする必要がある。

公開範囲・・・ログイン者に応じて表示するかしないかを設定したもの。
例えば、西村の場合、ログイン者が営業部または技術部の課長以上のみに表示するように公開範囲を設定しています(ログイン者がリーダーだったり、人事部だったりした場合は表示しない)
※{}の場合は全員に公開の意味です。
例)公開範囲=役職:{}、部署:技術部だったら、技術部の人には誰でも公開し、技術部以外の人だったら非公開にします。

JSON

1{ 2 //-------------------- 3 //従業員コレクション 4 //-------------------- 5 "従業員": { 6 //-------------------- 7 //各ドキュメント 8 //-------------------- 9 "西村": { 10 //-------------------- 11 //各データ 12 //-------------------- 13 "年齢": 25, 14 "月給": "30万円", 15 "婚姻歴": "あり", 16 "部署": "技術部", 17 "役職": "平社員", 18 "公開範囲": { 19 "役職": "課長以上", 20 "部署": "営業部,技術部" 21 } 22 }, 23 "田中": { 24 "年齢": 40, 25 "月給": "35万円", 26 "婚姻歴": "なし", 27 "部署": "技術部", 28 "役職": "平社員", 29 "公開範囲": {} 30 }, 31 "秋山": { 32 "年齢": 31, 33 "月給": "60万円", 34 "婚姻歴": "なし", 35 "部署": "人事部", 36 "役職": "平社員", 37 "公開範囲": { 38 "役職": {}, 39 "部署": "技術部" 40 } 41 }, 42 "小田": { 43 "年齢": 45, 44 "月給": "70万円", 45 "婚姻歴": "あり", 46 "部署": "営業部", 47 "役職": "リーダー", 48 "公開範囲": { 49 "役職": "リーダー以上", 50 "部署": "人事部" 51 } 52 }, 53 "木村": { 54 "年齢": 33, 55 "月給": "83万円", 56 "婚姻歴": "あり", 57 "部署": "技術部", 58 "役職": "課長", 59 "公開範囲": { 60 "役職": "課長以上", 61 "部署": {} 62 } 63 }, 64 "岡部": { 65 "年齢": 56, 66 "月給": "130万円", 67 "婚姻歴": "なし", 68 "部署": "秘書室", 69 "役職": "部長", 70 "公開範囲": { 71 "役職": "課長以上", 72 "部署": "営業部,技術部,人事部" 73 } 74 } 75 } 76}

発生している問題・分からないこと

質問

こんなDB検索を実現する際、どのようにプログラムを組めばいいでしょうか?

例えば、秋山がログインしました。
ポータルサイト側の検索項目に「部署:技術部」で検索条件を掛けたとします。
その場合、「西村、田中、木村」がヒットしますが、秋山は人事部の平社員です。
なので、西村と木村はヒットされず、「田中のみ」を表示したいです。

例えば、岡部がログインしました。
ポータルサイト側の検索項目に「全社員を対象」で検索条件を掛けたとします。
その場合、「西村、田中、秋山、小田、木村、岡部」がヒットしますが、岡部は秘書室の部長です。
なので、「田中、木村」を表示したいです。

該当のソースコード

特になし

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

Google検索をしてみましたが、こういう構成のシステムでNoSQLを使った記事を見つける事が出来なかったので質問させて頂きました。

Firebaseからの単純なGetは以下のようになることは理解しています。

Dart

1final userDoc = await FirebaseFirestore 2 .instance 3 .collection('従業員') 4 .doc('西村') 5 .get();

Where句を使うパターンも下記記事で学習しました。

ただ、質問のようなものは結構複雑になるのでどう実現したらいいかまだ想像着かないのが現状です。

私が考えた案は、一旦ポータルサイト側の検索条件にヒットする全員をGetした上で、Dart関数内でループ処理させ、(ざっくりですみません→)「if ( userDoc[i].公開範囲.役職 == xxxxx ) 」みたいな感じで回していくのが早そうではありましたが、従業員数の増加に応じて処理が重くなる懸念もありそうだと感じました。
DB側で検索できたらいいなと思った次第です。

また、もし「このシステムの構成だったらAWSやNoSQL以外の方がいい」などあればご教授いただければ幸いです。

補足

特になし



その後追記(参考までにChatGPTに質問した結果を追記)

試しに、ChatGPT o4-mini(プログラミング領域特化モデル)に尋ねて見たところこのような結果が出力されました。

プロンプト

ある会社では従業員情報を下記のようなNoSQLのドキュメント指向データベースに保存している。 従業員情報は、従業員自身が社内ポータルサイトで検索・閲覧することができる。 社内ポータルサイトは、ログインID/PWの他に、部署名と役職名も入力した上でログインする必要がある。 公開範囲・・・ログイン者に応じて表示するかしないかを設定したもの。 例えば、西村の場合、ログイン者が営業部または技術部の課長以上のみに表示するように公開範囲を設定しています(ログイン者がリーダーだったり、人事部だったりした場合は表示しない) ※{}の場合は全員に公開の意味です。 例)公開範囲=役職:{}、部署:技術部だったら、技術部の人には誰でも公開し、技術部以外の人だったら非公開にします。 以下のJSONはNoSQLの構造です。 { "従業員": { "西村": { "年齢": 25, "月給": "30万円", "婚姻歴": "あり", "部署": "技術部", "役職": "平社員", "公開範囲": { "役職": "課長以上", "部署": "営業部,技術部" } }, "田中": { "年齢": 40, "月給": "35万円", "婚姻歴": "なし", "部署": "技術部", "役職": "平社員", "公開範囲": {} }, "秋山": { "年齢": 31, "月給": "60万円", "婚姻歴": "なし", "部署": "人事部", "役職": "平社員", "公開範囲": { "役職": {}, "部署": "技術部" } }, "小田": { "年齢": 45, "月給": "70万円", "婚姻歴": "あり", "部署": "営業部", "役職": "リーダー", "公開範囲": { "役職": "リーダー以上", "部署": "人事部" } }, "木村": { "年齢": 33, "月給": "83万円", "婚姻歴": "あり", "部署": "技術部", "役職": "課長", "公開範囲": { "役職": "課長以上", "部署": {} } }, "岡部": { "年齢": 56, "月給": "130万円", "婚姻歴": "なし", "部署": "秘書室", "役職": "部長", "公開範囲": { "役職": "課長以上", "部署": "営業部,技術部,人事部" } } } } こんなDB検索を実現する際、どのようにDartプログラムを組めばいいでしょうか? 例1)秋山がログインしました。ポータルサイト側の検索項目に「部署:技術部」で検索条件を掛けたとします。 その場合、「西村、田中、木村」がヒットしますが、秋山は人事部の平社員です。なので、西村と木村はヒットされず、「田中のみ」を表示したいです。 例2)岡部がログインしました。 ポータルサイト側の検索項目に「全社員を対象」で検索条件を掛けたとします。 その場合、「西村、田中、秋山、小田、木村、岡部」がヒットしますが、岡部は秘書室の部長です。 なので、「田中、木村」を表示したいです。 一般的なソースコードは「final userDoc = await FirebaseFirestore.instance.collection('従業員').doc('西村') .get();」になると思います。上記の「例1,例2」を実現するためのプログラムを作成してください。

出力結果

✅ 前提 Firestore コレクション名: 従業員 各ドキュメント名が従業員名(例: 西村, 田中) ログイン情報として 部署 と 役職 を使って可視性チェック 公開範囲に基づいて、表示対象を制限 ✅ Dartコード:アクセス制御付きの従業員検索 import 'package:cloud_firestore/cloud_firestore.dart'; Future<List<String>> fetchVisibleEmployees({ required String loginUserName, required String loginDepartment, required String loginPosition, String? searchDepartment, }) async { final employeeSnapshot = await FirebaseFirestore.instance.collection('従業員').get(); final allEmployees = employeeSnapshot.docs; // 役職の序列定義(昇順) const positionHierarchy = ['平社員', 'リーダー', '課長', '部長', '本部長', '役員']; int getRank(String? position) { return positionHierarchy.indexOf(position ?? ''); } List<String> visibleEmployees = []; for (var doc in allEmployees) { final data = doc.data(); final name = doc.id; // 自分自身は非表示(必要であれば除外) if (name == loginUserName) continue; // 検索フィルタ if (searchDepartment != null && data['部署'] != searchDepartment) continue; final visibility = data['公開範囲'] as Map<String, dynamic>? ?? {}; final allowedPositions = (visibility['役職'] as String?)?.split(',') ?? []; final allowedDepartments = (visibility['部署'] as String?)?.split(',') ?? []; // 公開条件チェック final isPublicToAll = visibility.isEmpty; final isPositionMatch = allowedPositions.isEmpty || getRank(loginPosition) >= getRank(allowedPositions.first); final isDepartmentMatch = allowedDepartments.isEmpty || allowedDepartments.contains(loginDepartment); if (isPublicToAll || (isPositionMatch && isDepartmentMatch)) { visibleEmployees.add(name); } } return visibleEmployees; } ✅ 使い方例 例1: 秋山(人事部・平社員)が「技術部」で検索 final result = await fetchVisibleEmployees( loginUserName: '秋山', loginDepartment: '人事部', loginPosition: '平社員', searchDepartment: '技術部', ); // → 出力: ['田中'] 例2: 岡部(秘書室・部長)が全社員検索 dart コピーする 編集する final result = await fetchVisibleEmployees( loginUserName: '岡部', loginDepartment: '秘書室', loginPosition: '部長', ); // → 出力: ['田中', '木村'] 🔍 解説 getRank() によって役職の序列比較を可能にしています。 公開範囲が {}(空)の場合は全員に公開。 "課長以上" や "リーダー以上" のような表現ではなく、明示的な役職名を , 区切りで定義している前提で設計しています。 より柔軟にするには "以上" ロジックに合わせて条件分岐を追加する必要があります(必要なら拡張可能です)。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

承知いたしました。従業員情報がNoSQLのドキュメント指向データベースに保存されており、ログイン者の部署と役職に基づいて公開範囲が設定されているのですね。ログイン時にはID/PWに加えて、部署名と役職名の入力も必須とのこと。公開範囲の設定例も理解いたしました。何か特定の質問や、このデータ構造に関して実現したい機能などございますでしょうか?

投稿2025/04/25 09:07

Melissa36D

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問