🤷
Cloud FunctionsでLintは後から設定する
自動設定は制約が厳しい!
Cloud FunctionsをTypeScriptで使ったときに、ESLint入れるとエラー連発して、結構ハマりました。難しすぎる😱
初心者向けに、制約を緩くしてESLintとprettierを設定します。
- どうやるのか?
- 最初から入れない.
- 後から追加する.
私がやった設定
Cloud FunctionsをESLintなしで、環境構築した後に、このような設定をしました。
ESLint、Prettierを設定する
- ターミナルからfunctionsディレクトリに移動する.
cd functions
- eslintをinstallするコマンドを実行する.
npm init @eslint/config
- Prettierをinstallする.
npm i prettier
- functionsディレクトリに[.prettierrc]ファイルを作成する.
touch functions/.prettierrc
- eslintrc.jsを設定する.
;と""つけないと、エラー出すよ!って設定です。
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"overrides": [
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"semi": ["error", "always"],
"quotes": ["error", "double"]
}
};
- prettierの設定
タブが2行で、;と""つけてねって設定です。
{
"tabWidth": 2,
"semi": true,
"doubleQuote": true
}
Firebaseを操作するコード
Firebaseのコンソールで操作をして動作を検証したコード。配列に、any型しか型定義できないのが、悩みですね。(string|number)と書いたら、エラー吐かれる!
index.ts
// Cloud Functions for Firebase SDKでCloud Functionsを作成し、トリガーを設定します。
import * as functions from "firebase-functions";
// FirestoreにアクセスするためのFirebase Admin SDKです。
import * as admin from "firebase-admin";
admin.initializeApp();
// Firestoreのインスタンスを取得。
const db = admin.firestore();
// 注文をするとショッピングカートに購入履歴が作成されるトリガー関数.
exports.createOrder = functions.firestore.document("orders/{orderID}").onCreate(async (snap, context) => {
const newValue = snap.data();
await db.collection("shoppingCart").add({
name: `購入者の名前: ${newValue.name}`,
goods: `購入した商品: ${newValue.goods}`,
price: `購入した商品の価格: ${newValue.price}`,
count: `購入した商品の数: ${newValue.count}`,
});
});
// 注文を更新するとショッピングカートの購入履歴を更新するトリガー関数
exports.updateOrder = functions.firestore.document("orders/{orderID}").onUpdate(async(snap, context) => {
const newValue = snap.after.data();
const updatePromisse: any[] = [];
const snapshot = await db.collection("shoppingCart").get();
snapshot.forEach(doc => {
updatePromisse.push(db.collection("shoppingCart").doc(doc.id).update({
name: `購入者の名前: ${newValue.name}`,
goods: `購入した商品: ${newValue.goods}`,
price: `購入した商品の価格: ${newValue.price}`,
count: `購入した商品の数: ${newValue.count}`,
}));
});
await Promise.all(updatePromisse);
});
// 注文が削除されたら、ショッピングカートの購入履歴を削除するトリガー関数
exports.deleteOrder = functions.firestore.document("orders/{orderID}").onDelete(async(sanp, context) => {
const deletePromise: any[] = [];
const snapshot = await db.collection("shoppingCart").get();
snapshot.forEach(doc => {
deletePromise.push(db.collection("shoppingCart").doc(doc.id).delete());
});
await Promise.all(deletePromise);
});
// -----------------------------
// 退会テスト
// ユーザーが新規登録されたら、usersコレクションにメールの情報が保存されるトリガー関数
exports.sendWelcomeEmail = functions.auth.user().onCreate(async (user) => {
await db.collection("users").add({
email: user.email,
});
});
// userが削除されたら、userコレクションを削除するトリガー関数
exports.sendByeEmail = functions.auth.user().onDelete(async (user) => {
const deletePromise: any[] = [];
const snapshot = await db.collection("users").get();
snapshot.forEach(doc => {
deletePromise.push(db.collection("users").doc(doc.id).delete());
});
await Promise.all(deletePromise);
});
// 削除するユーザーを登録するコレクションが作成されたら、FirebaseAuthenticatonのユーザーデータを削除する.
// リージョンは、asia-northeast1を設定。自分の設定したリージョンに合わせる。
exports.deleteUser = functions.region("asia-northeast1").firestore.document("deleted_users/{docId}").onCreate(async (snap, context) => {
const deleteDocument = snap.data();
const uid = deleteDocument.uid;
await admin.auth().deleteUser(uid);
});
まとめ
DefaultのESLint使うと、謎のコメントをつけないとエラー消えなかったりして、結構悩まされました。Lintの設定は、規則がなければ、ゆる〜くしたいですね。
Discussion