jpskill.com
🛠️ 開発・MCP コミュニティ

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本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
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
🪟 Windows (PowerShell)
$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. 1. 下の青いボタンを押して gcp-firestore.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → gcp-firestore フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

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