gcp-firestore
Google Cloud Firestoreを活用し、コレクションとドキュメントでデータを整理、複合インデックスで効率的な検索、リアルタイム更新のリスナー設定、オフラインでのデータ保持、クライアント側のアクセス制御セキュリティルール作成を可能にするSkill。
📜 元の英語説明(参考)
Build real-time applications with Google Cloud Firestore. Model data with collections and documents, execute queries with composite indexes, set up real-time listeners for live updates, enable offline persistence, and write security rules for client-side access control.
🇯🇵 日本人クリエイター向け解説
Google Cloud Firestoreを活用し、コレクションとドキュメントでデータを整理、複合インデックスで効率的な検索、リアルタイム更新のリスナー設定、オフラインでのデータ保持、クライアント側のアクセス制御セキュリティルール作成を可能にするSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o gcp-firestore.zip https://jpskill.com/download/14931.zip && unzip -o gcp-firestore.zip && rm gcp-firestore.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/14931.zip -OutFile "$d\gcp-firestore.zip"; Expand-Archive "$d\gcp-firestore.zip" -DestinationPath $d -Force; ri "$d\gcp-firestore.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
gcp-firestore.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
gcp-firestoreフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
GCP Firestore
Cloud Firestore は、柔軟でスケーラブルな NoSQL ドキュメントデータベースです。リアルタイム同期、オフラインアクセスをサポートし、自動的にスケールします。ネイティブモード(リアルタイム+オフライン)と Datastore モード(サーバー専用、高スループット)で使用できます。
コアコンセプト
- Document — フィールド(JSON オブジェクトのようなもの)を含むレコードで、ID によって識別されます。
- Collection — ドキュメントのグループ
- Subcollection — ドキュメントの下にネストされたコレクション
- Reference — ドキュメントまたはコレクションの場所へのポインタ
- Real-time listener — ドキュメントまたはクエリへのライブ変更をストリーム配信します。
- Security Rules — クライアント SDK 用の宣言的なアクセス制御
CRUD 操作
# Initialize and write documents
from google.cloud import firestore
db = firestore.Client()
# Create or overwrite a document
db.collection('users').document('user-001').set({
'name': 'Alice Johnson',
'email': 'alice@example.com',
'role': 'admin',
'created_at': firestore.SERVER_TIMESTAMP
})
# Add a document with auto-generated ID
ref = db.collection('orders').add({
'user_id': 'user-001',
'items': [
{'name': 'Widget', 'qty': 2, 'price': 29.99},
{'name': 'Gadget', 'qty': 1, 'price': 49.99}
],
'total': 109.97,
'status': 'pending',
'created_at': firestore.SERVER_TIMESTAMP
})
print(f"Created order: {ref[1].id}")
# Read a document
doc = db.collection('users').document('user-001').get()
if doc.exists:
print(f"User: {doc.to_dict()}")
# Update specific fields (merge)
db.collection('users').document('user-001').update({
'role': 'superadmin',
'updated_at': firestore.SERVER_TIMESTAMP
})
# Update nested fields
db.collection('users').document('user-001').update({
'preferences.theme': 'dark',
'preferences.notifications': True
})
# Delete a document
db.collection('users').document('user-001').delete()
# Delete a specific field
db.collection('users').document('user-001').update({
'temporary_field': firestore.DELETE_FIELD
})
クエリ
# Simple queries
users_ref = db.collection('users')
# Filter by field
admins = users_ref.where('role', '==', 'admin').stream()
# Multiple conditions
recent_orders = db.collection('orders') \
.where('status', '==', 'pending') \
.where('total', '>=', 50) \
.order_by('total', direction=firestore.Query.DESCENDING) \
.limit(20) \
.stream()
for order in recent_orders:
print(f"{order.id}: ${order.to_dict()['total']}")
# Pagination with cursors
first_page = db.collection('orders') \
.order_by('created_at', direction=firestore.Query.DESCENDING) \
.limit(25) \
.get()
# Get next page starting after last document
last_doc = first_page[-1]
next_page = db.collection('orders') \
.order_by('created_at', direction=firestore.Query.DESCENDING) \
.start_after(last_doc) \
.limit(25) \
.get()
# Array and IN queries
# Find users with a specific tag
db.collection('users').where('tags', 'array_contains', 'premium').stream()
# Find orders with specific statuses
db.collection('orders').where('status', 'in', ['pending', 'processing']).stream()
リアルタイムリスナー
// real-time-listener.js — listen for live document changes
const { Firestore } = require('@google-cloud/firestore');
const db = new Firestore();
// Listen to a single document
const unsubscribe = db.collection('orders').doc('order-001')
.onSnapshot((doc) => {
if (doc.exists) {
console.log('Order updated:', doc.data());
}
});
// Listen to a query (all pending orders)
const queryUnsubscribe = db.collection('orders')
.where('status', '==', 'pending')
.onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === 'added') {
console.log('New order:', change.doc.data());
} else if (change.type === 'modified') {
console.log('Updated order:', change.doc.data());
} else if (change.type === 'removed') {
console.log('Removed order:', change.doc.id);
}
});
});
// Stop listening
// unsubscribe();
バッチ書き込みとトランザクション
# Batch write (up to 500 operations)
batch = db.batch()
for i in range(100):
ref = db.collection('products').document(f'product-{i:04d}')
batch.set(ref, {
'name': f'Product {i}',
'price': round(9.99 + i * 0.5, 2),
'in_stock': True
})
batch.commit()
print("Batch write complete")
# Transaction for atomic read-modify-write
@firestore.transactional
def transfer_funds(transaction, from_ref, to_ref, amount):
from_doc = from_ref.get(transaction=transaction)
to_doc = to_ref.get(transaction=transaction)
from_balance = from_doc.get('balance')
if from_balance < amount:
raise ValueError('Insufficient funds')
transaction.update(from_ref, {'balance': from_balance - amount})
transaction.update(to_ref, {'balance': to_doc.get('balance') + amount})
transaction = db.transaction()
transfer_funds(
transaction,
db.collection('accounts').document('alice'),
db.collection('accounts').document('bob'),
50.00
)
Security Rules
// firestore.rules — access control for client SDKs
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Users can read/write their own profile
match /users/{userId} {
allow read: if request.auth != null;
allow write: if request.auth.uid == userId;
}
// Orders: owner can read, only server can write
match /orders/{orderId} {
allow read: if request.auth.uid == resource.data.user_id;
allow create: if request.auth != null
&& request.resource.data.user_id == request.auth.uid
&& request.resource.data.total > 0;
allow update, delete: if false; // server-side only
}
// Public read, admin write
match /products/{productId} {
allow read: i 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
GCP Firestore
Cloud Firestore is a flexible, scalable NoSQL document database. It supports real-time synchronization, offline access, and scales automatically. Available in Native mode (real-time + offline) and Datastore mode (server-only, higher throughput).
Core Concepts
- Document — a record containing fields (like a JSON object), identified by ID
- Collection — a group of documents
- Subcollection — a collection nested under a document
- Reference — a pointer to a document or collection location
- Real-time listener — streams live changes to documents or queries
- Security Rules — declarative access control for client SDKs
CRUD Operations
# Initialize and write documents
from google.cloud import firestore
db = firestore.Client()
# Create or overwrite a document
db.collection('users').document('user-001').set({
'name': 'Alice Johnson',
'email': 'alice@example.com',
'role': 'admin',
'created_at': firestore.SERVER_TIMESTAMP
})
# Add a document with auto-generated ID
ref = db.collection('orders').add({
'user_id': 'user-001',
'items': [
{'name': 'Widget', 'qty': 2, 'price': 29.99},
{'name': 'Gadget', 'qty': 1, 'price': 49.99}
],
'total': 109.97,
'status': 'pending',
'created_at': firestore.SERVER_TIMESTAMP
})
print(f"Created order: {ref[1].id}")
# Read a document
doc = db.collection('users').document('user-001').get()
if doc.exists:
print(f"User: {doc.to_dict()}")
# Update specific fields (merge)
db.collection('users').document('user-001').update({
'role': 'superadmin',
'updated_at': firestore.SERVER_TIMESTAMP
})
# Update nested fields
db.collection('users').document('user-001').update({
'preferences.theme': 'dark',
'preferences.notifications': True
})
# Delete a document
db.collection('users').document('user-001').delete()
# Delete a specific field
db.collection('users').document('user-001').update({
'temporary_field': firestore.DELETE_FIELD
})
Queries
# Simple queries
users_ref = db.collection('users')
# Filter by field
admins = users_ref.where('role', '==', 'admin').stream()
# Multiple conditions
recent_orders = db.collection('orders') \
.where('status', '==', 'pending') \
.where('total', '>=', 50) \
.order_by('total', direction=firestore.Query.DESCENDING) \
.limit(20) \
.stream()
for order in recent_orders:
print(f"{order.id}: ${order.to_dict()['total']}")
# Pagination with cursors
first_page = db.collection('orders') \
.order_by('created_at', direction=firestore.Query.DESCENDING) \
.limit(25) \
.get()
# Get next page starting after last document
last_doc = first_page[-1]
next_page = db.collection('orders') \
.order_by('created_at', direction=firestore.Query.DESCENDING) \
.start_after(last_doc) \
.limit(25) \
.get()
# Array and IN queries
# Find users with a specific tag
db.collection('users').where('tags', 'array_contains', 'premium').stream()
# Find orders with specific statuses
db.collection('orders').where('status', 'in', ['pending', 'processing']).stream()
Real-Time Listeners
// real-time-listener.js — listen for live document changes
const { Firestore } = require('@google-cloud/firestore');
const db = new Firestore();
// Listen to a single document
const unsubscribe = db.collection('orders').doc('order-001')
.onSnapshot((doc) => {
if (doc.exists) {
console.log('Order updated:', doc.data());
}
});
// Listen to a query (all pending orders)
const queryUnsubscribe = db.collection('orders')
.where('status', '==', 'pending')
.onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === 'added') {
console.log('New order:', change.doc.data());
} else if (change.type === 'modified') {
console.log('Updated order:', change.doc.data());
} else if (change.type === 'removed') {
console.log('Removed order:', change.doc.id);
}
});
});
// Stop listening
// unsubscribe();
Batch Writes and Transactions
# Batch write (up to 500 operations)
batch = db.batch()
for i in range(100):
ref = db.collection('products').document(f'product-{i:04d}')
batch.set(ref, {
'name': f'Product {i}',
'price': round(9.99 + i * 0.5, 2),
'in_stock': True
})
batch.commit()
print("Batch write complete")
# Transaction for atomic read-modify-write
@firestore.transactional
def transfer_funds(transaction, from_ref, to_ref, amount):
from_doc = from_ref.get(transaction=transaction)
to_doc = to_ref.get(transaction=transaction)
from_balance = from_doc.get('balance')
if from_balance < amount:
raise ValueError('Insufficient funds')
transaction.update(from_ref, {'balance': from_balance - amount})
transaction.update(to_ref, {'balance': to_doc.get('balance') + amount})
transaction = db.transaction()
transfer_funds(
transaction,
db.collection('accounts').document('alice'),
db.collection('accounts').document('bob'),
50.00
)
Security Rules
// firestore.rules — access control for client SDKs
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Users can read/write their own profile
match /users/{userId} {
allow read: if request.auth != null;
allow write: if request.auth.uid == userId;
}
// Orders: owner can read, only server can write
match /orders/{orderId} {
allow read: if request.auth.uid == resource.data.user_id;
allow create: if request.auth != null
&& request.resource.data.user_id == request.auth.uid
&& request.resource.data.total > 0;
allow update, delete: if false; // server-side only
}
// Public read, admin write
match /products/{productId} {
allow read: if true;
allow write: if request.auth.token.admin == true;
}
}
}
# Deploy security rules
firebase deploy --only firestore:rules
Indexes
// firestore.indexes.json — composite indexes for complex queries
{
"indexes": [
{
"collectionGroup": "orders",
"queryScope": "COLLECTION",
"fields": [
{"fieldPath": "status", "order": "ASCENDING"},
{"fieldPath": "total", "order": "DESCENDING"}
]
},
{
"collectionGroup": "orders",
"queryScope": "COLLECTION",
"fields": [
{"fieldPath": "user_id", "order": "ASCENDING"},
{"fieldPath": "created_at", "order": "DESCENDING"}
]
}
]
}
# Deploy indexes
firebase deploy --only firestore:indexes
Best Practices
- Design data around your queries — denormalize for read performance
- Use subcollections for large lists that are always accessed per parent
- Keep documents small (<1MB); use subcollections for unbounded lists
- Use transactions for operations that need atomicity across documents
- Create composite indexes for queries with multiple where/orderBy clauses
- Use security rules for all client-accessible data — never trust the client
- Use batch writes for bulk operations (up to 500 per batch)
- Enable offline persistence for mobile apps with poor connectivity