【memberIds】自分が所属するチームだけを取得するための配列を用意する
このページでやること
このページでは、memberIds という配列を使って、「自分が所属しているチームだけ」を表示できるようにする考え方を理解します。
配列とは、複数の値をひとまとめにして持つデータです。
今回のアプリでは、各チームの中に次のような形で memberIds を保存します。
memberIds: [uid1, uid2, uid3]
これは、「このチームには、この3人が参加しています」という意味です。
今日のゴール
今日のゴールは、次の流れを理解することです。
チームを作る
↓
teams/{teamId} に memberIds を保存する
↓
ログイン中ユーザーの uid を使う
↓
自分が参加しているチームだけ取得できる
あとでトーク一覧画面では、次の検索に使います。
.where('memberIds', arrayContains: uid)
今は、まずこの memberIds を正しく保存するところまで進めます。
このページで出てくる単語
| 単語 | 一言説明 |
|---|---|
memberIds | チーム参加者のuid一覧 |
| 配列 | 複数の値をまとめたデータ |
uid | ユーザーごとのID |
arrayContains | 配列の中にその値が入っているか調べる条件 |
teams/{teamId} | チーム情報を保存する場所 |
ownerId | チームを作った人のuid |
uid は、Firebase Authenticationがユーザーごとに作るIDです。
npmや環境変数はこのページで必要?
このページでは、npmは使いません。
環境変数も設定しません。
必要なのは、すでに使っている次の2つです。
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
このページでやることは、teams/{teamId} を作るときに memberIds を入れることです。
Step 1:main.dartを開く
次のファイルを開きます。
lib/main.dart
VS Codeを使っている場合は、ターミナルで次を実行してもOKです。
code lib/main.dart
Step 2:createTeam()を探す
main.dart の中で、次の関数を探します。
createTeam
VS Codeなら、次で検索できます。
command + F
検索文字はこちらです。
Future<void> createTeam
この createTeam() の中で、チーム情報を保存しています。
Step 3:teams/{teamId} を作る場所を見る
createTeam() の中に、次のようなコードがあります。
final teamRef = await FirebaseFirestore.instance.collection('teams').add({
'name': teamName,
'ownerId': user.uid,
'memberIds': [user.uid],
'createdAt': FieldValue.serverTimestamp(),
'updatedAt': FieldValue.serverTimestamp(),
});
この中で、一番大事なのはここです。
'memberIds': [user.uid],
これが、今回の主役です。
Step 4:memberIds とは何か
memberIds は、そのチームに所属しているユーザーの uid 一覧です。
たとえば、チーム作成者が abc123 なら、保存される形はこうです。
memberIds: [abc123]
まだ1人しかいないので、配列の中には1つだけ入ります。
あとでメンバーが増えると、こうなります。
memberIds: [abc123, xyz789, pqr456]
つまり、
このチームに所属している人のuidを、全部まとめて持っている
ということです。
Step 5:なぜ memberIds が必要なのか
トーク一覧画面では、「自分が所属しているチームだけ」を表示したいです。
たとえば、ログイン中ユーザーの uid が abc123 だとします。
そのとき、次のように探します。
memberIds に abc123 が入っているチームだけ
このために、teams/{teamId} の中に memberIds を保存しておきます。
もし memberIds がなければ、どのチームに自分が入っているかを探しにくくなります。
Step 6:arrayContains でどう使うのか
あとでチーム一覧を表示するとき、Firestoreでは次のような検索を使います。
.where('memberIds', arrayContains: uid)
これは、こういう意味です。
memberIds という配列の中に
今ログインしているユーザーの uid が入っているチームだけ取る
たとえば、
ログイン中ユーザー uid = abc123
チームデータがこうなら、
チームA memberIds: [abc123, xyz789]
チームB memberIds: [zzz111]
チームC memberIds: [abc123]
取得されるのはこうです。
チームA
チームC
チームBは取られません。
Step 7:今の段階では、まず保存できればOK
このページでは、まだ .where('memberIds', arrayContains: uid) を実装しません。
今のゴールは、チーム作成時に memberIds をちゃんと保存することです。
つまり、次の状態になっていればOKです。
final teamRef = await FirebaseFirestore.instance.collection('teams').add({
'name': teamName,
'ownerId': user.uid,
'memberIds': [user.uid],
'createdAt': FieldValue.serverTimestamp(),
'updatedAt': FieldValue.serverTimestamp(),
});
この1行が入っていれば、あとでチーム一覧を出せる準備が整います。
Step 8:なぜ ownerId だけではだめなのか
「ownerId があるなら、それで十分では?」と思うかもしれません。
でも、ownerId はチームを作った人1人しか持てません。
ownerId: abc123
これだと、あとから参加したメンバーを表せません。
たとえば、チームに3人いる場合はこうしたいです。
ownerId: abc123
memberIds: [abc123, xyz789, pqr456]
つまり、
| 項目 | 役割 |
|---|---|
ownerId | チーム作成者を記録する |
memberIds | 所属メンバー全員を記録する |
役割が違うので、両方必要です。
Step 9:members と memberIds の違い
ここも大事です。
今回のアプリでは、members サブコレクションも使っています。
teams/{teamId}/members/{uid}
では、members と memberIds は何が違うのでしょうか。
| データ | 役割 |
|---|---|
memberIds | 自分の参加チームを検索するため |
members | 名前、メール、権限を保存するため |
memberIds は検索用です。
members は詳細情報用です。
この2つを組み合わせることで、
チーム一覧は速く探せる
↓
チームの中では詳しいメンバー情報も見られる
ようになります。
Step 10:完成コードの確認
createTeam() の中の teams 作成部分が、次のようになっていればOKです。
final teamRef = await FirebaseFirestore.instance.collection('teams').add({
'name': teamName,
'ownerId': user.uid,
'memberIds': [user.uid],
'createdAt': FieldValue.serverTimestamp(),
'updatedAt': FieldValue.serverTimestamp(),
});
この中で見る場所は3つです。
name
ownerId
memberIds
特に memberIds: [user.uid] が入っているかを見てください。
Step 11:保存する
main.dart を保存します。
Macの場合:
command + S
Windowsの場合:
Ctrl + S
Step 12:実行する
ターミナルで実行します。
flutter run
すでに起動している場合は、ターミナルで r を押します。
r
必要なら R でホットリスタートします。
R
Step 13:チームを作る
アプリでログインします。
右下の + ボタンを押して、チームを作ります。
例として、次のように入力します。
開発チーム
作成後、Firebase Consoleで確認します。
Step 14:Firestoreで memberIds を確認する
Firebase Consoleを開きます。
https://console.firebase.google.com/
次の順番で確認します。
Firestore Database
↓
データ
↓
teams
↓
作成したteamId
中に、次の項目があるか確認します。
name
ownerId
memberIds
createdAt
updatedAt
特にここを見ます。
memberIds
中に、自分の uid が入っていれば成功です。
たとえば、こうです。
memberIds: ["abc123"]
Step 15:1か所だけ変更してみる
試しに、保存されるチーム名を少し変えて作ってみます。
新しいチームをもう1つ作ります。
例:
営業チーム
Firestoreを見ると、別の teamId で新しいドキュメントができているはずです。
その中にも、次の形で memberIds が入ります。
memberIds: ["同じ自分のuid"]
つまり、チームが違っても、自分が所属していれば自分のuidが入ります。
この感覚がつかめればOKです。
よくあるエラーと直し方
| エラー | 原因 | 直し方 |
|---|---|---|
memberIds がない | 保存コードに書いていない | 'memberIds': [user.uid], を追加する |
memberIds が文字になっている | 配列ではなく文字列で保存している | [user.uid] のように配列で書く |
permission-denied | Firestore Rulesで拒否されている | 開発用Rulesを確認する |
user.uid が取れない | ログインしていない | 先にログインする |
| チーム作成できない | createTeam() が正しくつながっていない | showCreateTeamSheet() と createTeam() を確認する |
memberIds** が文字列になってしまう例**
これはダメです。
'memberIds': user.uid,
これだと、ただの文字列になります。
今回欲しいのは配列なので、こう書きます。
'memberIds': [user.uid],
四角い [] がついているのが大事です。
最短作業まとめ
読むのが大変な人は、ここだけ見てください。
1. teams作成コードを確認
final teamRef = await FirebaseFirestore.instance.collection('teams').add({
'name': teamName,
'ownerId': user.uid,
'memberIds': [user.uid],
'createdAt': FieldValue.serverTimestamp(),
'updatedAt': FieldValue.serverTimestamp(),
});
2. memberIds は必ず配列で書く
'memberIds': [user.uid],
3. 保存して実行
flutter run
4. Firestoreで確認
Firestore Database
↓
teams
↓
作成したteamId
↓
memberIds
チェックリスト
□ main.dartを開いた
□ createTeam()を探した
□ teams/{teamId} の作成コードを見つけた
□ ownerIdがある
□ memberIdsがある
□ memberIdsに [user.uid] を入れた
□ memberIdsが配列になっている
□ 保存した
□ flutter runで起動した
□ チームを作成した
□ FirestoreでmemberIdsを確認した
ミニ確認問題
Q1. memberIds は何を保存するための項目ですか?
回答
そのチームに所属しているユーザーの uid 一覧を保存するための項目です。
Q2. なぜ memberIds は配列で保存しますか?
回答
チームには複数人が所属するからです。
1人だけではなく、複数の uid をまとめて持てるようにするためです。
Q3. ownerId だけでは足りない理由は何ですか?
回答
ownerId はチームを作った人1人しか表せません。
所属メンバー全員を表すには memberIds が必要です。
Q4. このページでnpmや環境変数は必要ですか?
回答
必要ありません。
このページでは、memberIds を配列で保存する形を整えるだけです。
このページのまとめ
memberIdsは、チーム所属ユーザーのuid一覧。memberIdsは配列で保存する。- チーム作成時は、最初に作成者の
uidを入れる。 ownerIdは作成者だけを表す。memberIdsは所属メンバー全体を表す。- あとで
arrayContainsを使って、自分が所属しているチームだけ取得できる。 membersは詳細情報用、memberIdsは検索用。- このページではnpmや環境変数は不要。
次のページでやること
次のページでは、where('memberIds', arrayContains: uid) を使って、ログイン中ユーザーが所属しているチームだけを一覧表示します。
