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

angular-fire

AngularFire v20以降で、Firestoreと認証をSignalsやDDDアーキテクチャと統合する際のベストプラクティスを提供するSkill。

📜 元の英語説明(参考)

Best practices and code patterns for @angular/fire version 20+, integrating Firestore and Auth with Signals and DDD architecture.

🇯🇵 日本人クリエイター向け解説

一言でいうと

AngularFire v20以降で、Firestoreと認証をSignalsやDDDアーキテクチャと統合する際のベストプラクティスを提供するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

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

🎯 この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-17
取得日時
2026-05-17
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

AngularFire & Firebase パターン スキル

🎯 目的

このスキルは、Zoneless、Signal-first、DDD準拠の Angular 20 アプリケーションで @angular/fire を使用するための実装パターンを提供します。

🛠️ コアパターン

1. リポジトリの実装 (インフラストラクチャ)

Firestore と Signals を使用してドメインリポジトリを実装する方法です。

// src/app/integration/persistence/task-firestore.repository.ts
import { inject, Injectable } from '@angular/core';
import { Firestore, collection, collectionData, query, where, doc, setDoc } from '@angular/fire/firestore';
import { toSignal } from '@angular/core/rxjs-interop';
import { TaskRepository } from '@domain/repositories';
import { TaskEntity } from '@domain/entities';

@Injectable({ providedIn: 'root' })
export class TaskFirestoreRepository implements TaskRepository {
  private firestore = inject(Firestore);
  private collection = collection(this.firestore, 'tasks');

  // Return Observable (Infrastructure Standard)
  findByWorkspace(workspaceId: string): Observable<TaskEntity[]> {
    const q = query(this.collection, where('workspaceId', '==', workspaceId));
    return collectionData(q, { idField: 'id' }) as Observable<TaskEntity[]>;
  }

  async save(task: TaskEntity): Promise<void> {
    const docRef = doc(this.firestore, `tasks/${task.id}`);
    await setDoc(docRef, task);
  }
}

2. Signal ベースの認証状態 (Account モジュール)

認証ストアを構築するための標準パターンです。

// src/app/account/application/stores/auth.store.ts
import { inject } from '@angular/core';
import { Auth, user } from '@angular/fire/auth';
import { toSignal } from '@angular/core/rxjs-interop';
import { signalStore, withState, withComputed } from '@ngrx/signals';

export const AuthStore = signalStore(
  { providedIn: 'root' },
  withComputed(() => {
    const auth = inject(Auth);
    // Transform Firebase User stream to Signal
    const currentUser = toSignal(user(auth));

    return {
      user: currentUser,
      isAuthenticated: computed(() => !!currentUser()),
      userId: computed(() => currentUser()?.uid ?? null)
    };
  })
);

3. エラーマッピング

Firebase のエラーは、ドメインや UI に直接到達すべきではありません。

try {
  await signInWithEmailAndPassword(this.auth, email, password);
} catch (error: any) {
  // Map Firebase Auth Error to Domain Error
  if (error.code === 'auth/wrong-password') {
    throw new InvalidCredentialsError();
  }
  throw new InfrastructureError(error.message);
}

🔐 セキュリティルールチェックリスト

  • [ ] すべてのワークスペースデータに対して request.auth != null を設定します。
  • [ ] ユーザーは自分がメンバーである workspaces のみを読み取ることができます。
  • [ ] 権限チェックには get(/databases/(default)/documents/workspaces/$(workspaceId)).data.members を使用します。
  • [ ] 開発環境であっても allow read, write: if true; は使用しません。

🚀 最適化パターン

  • Zoneless の安全性: すべての Firestore 操作が Angular Signals でラップされていることを確認し、変更検知の漏れを防ぎます。
  • スナップショット変換: ドメインエンティティに変換する際は、常に Timestamp オブジェクトを number (ミリ秒) にマッピングします。
  • バッチ処理: 複数の更新には writeBatch() を使用して、アトミック性を維持し、コストを節約します。
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

AngularFire & Firebase Patterns Skill

🎯 Purpose

This skill provides implementation patterns for using @angular/fire in a Zoneless, Signal-first, and DDD-compliant Angular 20 application.

🛠️ Core Patterns

1. Repository Implementation (Infrastructure)

How to implement a Domain Repository using Firestore and Signals.

// src/app/integration/persistence/task-firestore.repository.ts
import { inject, Injectable } from '@angular/core';
import { Firestore, collection, collectionData, query, where, doc, setDoc } from '@angular/fire/firestore';
import { toSignal } from '@angular/core/rxjs-interop';
import { TaskRepository } from '@domain/repositories';
import { TaskEntity } from '@domain/entities';

@Injectable({ providedIn: 'root' })
export class TaskFirestoreRepository implements TaskRepository {
  private firestore = inject(Firestore);
  private collection = collection(this.firestore, 'tasks');

  // Return Observable (Infrastructure Standard)
  findByWorkspace(workspaceId: string): Observable<TaskEntity[]> {
    const q = query(this.collection, where('workspaceId', '==', workspaceId));
    return collectionData(q, { idField: 'id' }) as Observable<TaskEntity[]>;
  }

  async save(task: TaskEntity): Promise<void> {
    const docRef = doc(this.firestore, `tasks/${task.id}`);
    await setDoc(docRef, task);
  }
}

2. Signal-Based Auth State (Account Module)

Standard pattern for building an Auth Store.

// src/app/account/application/stores/auth.store.ts
import { inject } from '@angular/core';
import { Auth, user } from '@angular/fire/auth';
import { toSignal } from '@angular/core/rxjs-interop';
import { signalStore, withState, withComputed } from '@ngrx/signals';

export const AuthStore = signalStore(
  { providedIn: 'root' },
  withComputed(() => {
    const auth = inject(Auth);
    // Transform Firebase User stream to Signal
    const currentUser = toSignal(user(auth));

    return {
      user: currentUser,
      isAuthenticated: computed(() => !!currentUser()),
      userId: computed(() => currentUser()?.uid ?? null)
    };
  })
);

3. Error Mapping

Firebase errors should not reach the Domain or UI directly.

try {
  await signInWithEmailAndPassword(this.auth, email, password);
} catch (error: any) {
  // Map Firebase Auth Error to Domain Error
  if (error.code === 'auth/wrong-password') {
    throw new InvalidCredentialsError();
  }
  throw new InfrastructureError(error.message);
}

🔐 Security Rules Checklist

  • [ ] request.auth != null for all workspace data.
  • [ ] Users can only read workspaces they are members of.
  • [ ] Use get(/databases/(default)/documents/workspaces/$(workspaceId)).data.members for permission checks.
  • [ ] No allow read, write: if true; even in development.

🚀 Optimization Patterns

  • Zoneless Safety: Ensure all Firestore interactions are wrapped in Angular Signals to avoid missing change detection.
  • Snapshot Transformation: Always map Timestamp objects to number (milliseconds) when converting to Domain Entities.
  • Batching: Use writeBatch() for multiple updates to maintain atomicity and save costs.