Nest.jsとFireStoreを連携させる
こんにちは、naoです。
今回普段使い慣れているNest.jsと個人開発の味方のFireStoreを
連携した手順を構築したいと思います。
Firebaseブロジェクト初期設定
firebase
ご自身のアカウントでログインをし、「プロジェクトを作成」をクリックします。
プロジェクト名を任意のもので設定をし、「続行」をクリックします。
次にFirebaseプロジェクトのAIアシスタンス設定の画面に遷移しますが
こちらはお好みで有効にします(この機能が追加されているのを知らなかった)
次にg4の有効化について聞かれますが、バックエンドとしてFireStoreを使うだけなので
ここはOFFにします。
その後、プロジェクトが作成されるので「続行」をクリックしましょう。
作成したプロジェクトに遷移すると思います。
FireStore設定
プロジェクトのサイドバーから「Firestore Database」をクリック->「データベースを作成」
ロケーションを今回は「asia-northeast1 (Tokyo)」に選択
次にルールについて問われますが、一旦「テストモード」で開始します。
Firebaseプロジェクト webアプリ設定
次にwebアプリの設定をします。
firebaseを使うのにはkey等が必要なのでこれから取得するための設定をします。
サイドバー上の設定アイコンをクリックし、「全般」タブを下までスクロールし
マイアプリのWebアイコンをクリック
アプリのニックネームは任意のもの。「Hosting」は使用しないのでチェックを外しましょう。
次にFirebase SDKの追加は「npmを使用する」をチェックし「コンソールに進む」をクリック
。
次にサイドバー上の設定アイコンをクリックし、「サービスアカウント」タブを下までスクロールし
今回はNode.jsを使用するので、チェックをし、「新しい秘密鍵を生成」をクリック。
こちらは後ほど、Nest.jsに設定で使用するので、ご自身がわかる場所に保存してください。
Nest.jsアプリケーションの作成
ここからはNest.jsのアプリを作成します。
まだ@nestjs/cliはグローバルにインストールした上でアプリを作成しましょう。
パッケージマネージャの選択を求められるので、任意のもので。
作成後はサーバを立ち上げます。
http://localhost:3000/ にて「Hello World!」が出ればOKです👍
npm i -g @nestjs/cli
nest new project-name
npm run dev:start
Nest.js firebase-admin設定
次に先ほど作成したfirebaseプロジェクトを組み込んでいきます。
npmライブラリではfirebase
とfirebase-admin
があるのですが、違いは以下
項目 | Firebase SDK | Firebase Admin SDK |
---|---|---|
使用環境 | クライアントサイド (Web, iOS, Android) | サーバーサイド (Node.js, Java, Python など) |
権限レベル | ユーザーごとのアクセス制御(セキュリティルール適用) | 管理者権限(セキュリティルールを無視可能) |
主な用途 | エンドユーザーの認証、データの読み書き、リアルタイム通信 | ユーザー管理、データベース管理、プッシュ通知送信 |
認証関連 | ユーザー自身の認証・ログイン処理をサポート | ユーザーの作成・更新・削除、カスタム認証 |
データ操作 | Firestore・Realtime Database へのアクセス(ルール適用) | 制限なしで DB 管理・操作 |
プッシュ通知 | クライアントから通知を受け取る | FCM(Firebase Cloud Messaging)で通知送信が可能 |
適用事例 | アプリのフロントエンドでのデータ取得・操作 | バックエンドでの管理業務・バッチ処理 |
今回はfirebase-adminを使用します。
公式ドキュメント
合わせて@nestjs/configもインストールします。
@nestjs/config は NestJS で環境変数や設定ファイルを管理するための公式パッケージです。
アプリケーションの設定を 環境変数 (.env) や 設定ファイル から簡単に読み込めるようになります。
npm install firebase-admin --save
npm install @nestjs/config
次にルートディレクトに.envを作成し、firebase web設定で取得をした
secret.keyの中身を見て以下の箇所を書き換えます。
FIREBASE_PROJECT_ID=
FIREBASE_CREDENTIALS=
FIREBASE_CLIENT_EMAIL=
次にsrc/common/firebaseのディレクトリを作成し、その配下に
service.tsとmodule.tsを作成します。
import { Module } from '@nestjs/common';
import { FirebaseService } from './service';
@Module({
providers: [FirebaseService],
exports: [FirebaseService],
})
export class FirebaseModule {}
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as admin from 'firebase-admin';
@Injectable()
export class FirebaseService {
private firebaseAdmin: admin.app.App;
constructor(private readonly configService: ConfigService) {
const projectId = this.configService.get<string>('FIREBASE_PROJECT_ID');
const clientEmail = this.configService.get<string>('FIREBASE_CLIENT_EMAIL');
const privateKey = this.configService
.get<string>('FIREBASE_CREDENTIALS')
?.replace(/\\n/g, '\n');
this.firebaseAdmin = admin.initializeApp({
credential: admin.credential.cert({
projectId,
clientEmail,
privateKey,
}),
});
}
get admin() {
return this.firebaseAdmin;
}
}
api作成
ここからはルートにあるapp.module,service,controllerを使用して
firestoreにinsertするapiを作成しましょう。
まずはapp.moduleで先ほど作成したModuleをimportします。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { FirebaseModule } from './common/module/firebase/module';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
// isGlobal: trueは、このConfigModuleをアプリケーション全体で利用可能にするフラグです。
// trueに設定すると、他のモジュールでConfigModuleをインポートする必要がなくなります。
ConfigModule.forRoot({ isGlobal: true, envFilePath: ['.env'] }),
FirebaseModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
次にコントローラでエンドポイントを定義します。
今回は仮ですがtodoInsertという名前をGETリクエストで受け付けるようにしました。
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
todoInsert() {
return this.appService.todoInsert();
}
}
次はserviceです。仮ですのでGETリクエストが/に来たら
用意したjsonをtodosコレクションにinsertします。
import { Injectable } from '@nestjs/common';
import { FirebaseService } from './common/module/firebase/service';
@Injectable()
export class AppService {
constructor(private readonly firebase: FirebaseService) {}
async todoInsert(): Promise<string> {
try {
const todoData = {
title: 'Sample TODO',
description: 'This is a sample TODO item.',
createdAt: new Date(),
completed: false,
};
const docRef = await this.firebase.admin
.firestore()
.collection('todos')
.add(todoData);
return `TODOが追加されました: ${docRef.id}`;
} catch (error) {
console.error('TODOの追加に失敗しました:', error);
return 'TODOの追加に失敗しました';
}
}
}
動作確認
ご自身のAPIクライアントツールから
localhost:3000/に対してGETリクエストで送信してください。
実際にfirestoreに登録されているかを確認します。
登録することができました🥹
まとめ
今回はNest.jsとfirestoreを連携させる部分について解説をしました。
個人開発の味方であるfirestoreを使ってたくさんアプリを作っていきたいと思います!!
Discussion