ドキュメント参照
ドキュメント参照は、コレクション内の特定のレコードを指すポインタであり、個別のドキュメントの読み取り、書き込み、削除に使用されます。
ドキュメント参照を使用する理由
データベース内の特定のドキュメントを読み取り、書き込み、または削除する必要があります。ドキュメント参照は単一レコードへの直接的なポインタを提供し、コレクション全体をクエリせずにそのレコードに対して操作を実行できます。
// 特定のユーザーへの参照を取得してデータを読み取る
const userRef = squid.collection<User>('users').doc('user_123');
const user = await userRef.snapshot();
console.log(user?.name);
概要
ドキュメントは、リレーショナルデータベースのテーブルの行、または NoSQL データベースのドキュメントを指すことがあります。ドキュメント参照は、その特定レコードへの型付きポインタとして機能します。
ドキュメント参照は存在しないドキュメントを指すこともできます。これは、参照に対して insert を呼び出して新しいドキュメントを作成する方法です。
collection 内のドキュメントへの参照を取得するには、doc メソッドに document ID を渡します。
const userRef = squid.collection<User>('users').doc('user_123');
クイックスタート
Step 1: コレクション参照を作成してドキュメントを取得する
interface User {
id: string;
name: string;
email: string;
}
const usersCollection = squid.collection<User>('users');
const userRef = usersCollection.doc('user_123');
Step 2: ドキュメントデータを読み取る
// 単発の snapshot(ドキュメントが存在しない場合はデータまたは undefined を返す)
const user = await userRef.snapshot();
if (user) {
console.log(user.name, user.email);
}
Step 3: ドキュメントにデータを書き込む
// 新しいドキュメントを insert する
await usersCollection.doc('new_user').insert({
id: 'new_user',
name: 'Alice',
email: 'alice@example.com',
});
// 既存のドキュメントを update する
await userRef.update({ email: 'newemail@example.com' });
コアコンセプト
snapshot vs snapshots
ドキュメント参照には、データを読み取る方法が 2 つあります。
snapshot()はPromise<T | undefined>を返し、現在のドキュメントデータ、またはドキュメントが存在しない場合はundefinedで解決されます。単発の読み取りに使用します。snapshots()は、T | undefinedの RxJS Observable を返し、ドキュメントが変更されるたびに最新データを emit します。リアルタイム更新に使用します。
// 単発の読み取り(データを直接返す)
const user = await userRef.snapshot();
if (user) {
console.log(user.name); // User フィールドへの型付きアクセス
}
// リアルタイム購読
userRef.snapshots().subscribe((user) => {
console.log('User updated:', user);
});
クエリ結果における data getter
query().snapshot() で複数ドキュメントをクエリすると、結果は DocumentReference<T>[] として返されます。各 DocumentReference には、型付きデータにアクセスするための data getter があります。
const users = await squid.collection<User>('users').query().snapshot();
for (const userRef of users) {
const name: string = userRef.data.name; // .data 経由の型安全なアクセス
}
代わりに、dereference() を使うとドキュメント参照なしでデータを直接取得できます。詳細は Queries を参照してください。
存在しないドキュメントを参照する
まだ存在しないドキュメントへの参照を作成できます。これは新しいドキュメントを insert する標準的な方法です。
// このドキュメントはまだ存在しない
const newUserRef = squid.collection<User>('users').doc('new_user_id');
// データを insert して作成する
await newUserRef.insert({
id: 'new_user_id',
name: 'Bob',
email: 'bob@example.com',
});
自動生成 ID を使う場合は、引数なしで doc() を呼び出します。詳細は Document IDs を参照してください。
エラーハンドリング
| Error | Cause | Solution |
|---|---|---|
| Document not found | ドキュメントが存在しないため snapshot() が null を返した | data にアクセスする前に null をチェックする |
| Invalid document ID | ID 形式がコレクションのキー・スキーマに一致しない | built-in database では文字列 ID を使用するか、external connectors ではオブジェクト ID を使用する |
| Security rule rejection | 変更(mutation)が security rules によりブロックされた | その操作に対する権限がユーザーにあることを確認する |
ベストプラクティス
-
ドキュメントが存在しない可能性があるため、読み取り時は 常に undefined をチェック してください。
Client codeconst user = await userRef.snapshot();
if (!user) {
console.log('User not found');
return;
}
console.log(user.name); -
リアルタイム更新が必要な UI バインディングには
snapshots()を、フォームの事前入力のような単発の読み取りにはsnapshot()を使用します。 -
既存ドキュメントを変更する場合は、変更したフィールドのみを送信するために
insert()よりupdate()を優先 してください。詳細は Adding data を参照してください。
関連項目
- Document IDs - built-in および external databases の ID 形式
- Collection references - コレクションとテーブルにアクセスする
- Queries - フィルター、ソート、join を使ってドキュメントをクエリする
- Adding data - insert と update 操作
- Deleting data - delete 操作