Home

Firestoreから取得したドキュメントのTimestampをDateに変換する

September 16, 2021

Firestore のデータ型の1つに Timestamp 型があります。これは Firestore 独自の型です。

Timestamp が持っている toDate() メソッドを呼び出すと、JavaScript の Date 型に変換することができます。クライアント側でデータを取得した後、データを操作する際にまず toDate() を呼び出すというのはよくある動きだと思います。

...

Firestoreの全ドキュメントを削除する処理

September 15, 2021

例えばローカルのエミュレータ環境の Firestore へシードデータを流す際、シーディングの初期化処理としてデータを全削除したいというシチュエーションはよくあると思います。

...

FirestoreからBigQueryにデータ連携してSQLでデータを取得する手順

September 1, 2021

Firestore の苦手とする部分として複雑な検索条件をもとにデータを取得するのが困難です。

  • そのような要件のあるサービスに対してそもそも Firestore を選定するべきではない
  • Firestore のデータ構造を最適化することにより解決する
  • クライアントサイドジョインを用いて解決する
  • 検索用のデータベースを別に用意しそちらからデータを取得する

選択肢としては上記が考えられます。

...

TypeScriptで関数の引数や戻り値から型を取得する

August 28, 2021

関数の引数から型を取得 #

  • Parameters<typeof (function name)>
const greet = (name: string, word: 'Hello' | 'Good Bye') => {
  return `${word}, ${name}!`;
};

type Args = Parameters<typeof greet>; // [name: string, word: "Hello" | "Good Bye"]
type firstArg = Args['0']; // string
type secondArg = Args['1']; //  "Hello" | "Good Bye"

関数の戻り値から型を取得 #

  • ReturnType<typeof (function name)>
const getUser = () => ({
  name: 'Alice',
  age: 20,
  sex: 'female',
  hasPhone: true,
  friends: ['Bob', 'Charlie', 'David'],
  school: {
    name: 'Awesome University',
    major: 'cs',
  },
});

type User = ReturnType<typeof getUser>;

// {
//   name: string;
//   age: number;
//   sex: string;
//   hasPhone: boolean;
//   friends: string[];
//   school: {
//     name: string;
//     major: string;
// };

関数の戻り値から型を取得(非同期関数) #

  • ReturnType<typeof (function name)> extends Promise<infer T> ? T : never
  • ReturnType<typeof (function name)> extends PromiseLike<infer T> ? T : never
const getUser = async () => ({
  name: 'Alice',
  age: 20,
  sex: 'female',
  hasPhone: true,
  friends: ['Bob', 'Charlie', 'David'],
  school: {
    name: 'Awesome University',
    major: 'cs',
  },
});

type User = ReturnType<typeof getUser> extends Promise<infer T> ? T : never;

// {
//   name: string;
//   age: number;
//   sex: string;
//   hasPhone: boolean;
//   friends: string[];
//   school: {
//     name: string;
//     major: string;
// };

補足

...

TypeScriptでEnumな配列やオブジェクトから型を取得する

August 27, 2021

配列から型を取得 #

typeof xxx[number]

const names = ['Alice', 'Bob', 'Charlie', 'David'] as const;

type Names = typeof names[number]; // "Alice" | "Bob" | "Charlie" | "David"

オブジェクトのキーから型を取得 #

keyof typeof xxx

const favoriteColors = {
  alice: 'cyan',
  bob: 'magenta',
  charlie: 'yellow',
  david: 'black',
} as const;

type FavoriteColors = keyof typeof favoriteColors; // "alice" | "bob" | "charlie" | "david"

オブジェクトのバリューから型を取得 #

typeof xxx[keyof typeof xxx]

...

メール送受信に関する仕組みやドメイン設定のこと

August 25, 2021

作業にあたり掲題の件で調べることがあった。頻繁に使用する知識でもないため、忘れた時のためにここに記録しておく。

メール送信について #

送信元の偽装 #

メール受信時に表示される送信元アドレスを偽装する(実際の送信元とは異なるアドレスを表示する)ことは簡単に行える。表示される送信元には送信者が任意の内容を設定できるためである。なぜこのようなことが起きるのか、以下の記事がわかりやすい。

...

有名なデザインガイドラインまとめ

July 10, 2021

デザインガイドライン #

デザインとして取り決めを設定し共通認識をもたせたりする必要がある場合、デザインではガイドラインを定め運用する。 ユーザビリティ、ヒューマンインターフェース、コンピュータアクセシビリティなどを高めるため、情報デザイン、ウェブデザインの分野などで BTRON のように初めて使用するアプリケーションであっても混乱がないよう、メニューの並び順なども規格化し、多言語の利用についても考慮されたデザインガイドラインが既定されている。フォントなどは Roboto などのように Android や Chrome OS のシステムフォントに採用されており、マテリアルデザインのデザインガイドラインでも利用が推奨されている。 アップルではデザインガイドライン「Aqua Human Interface Guidelines」を設けこれに従ったレイアウトが容易に行えるようになっている。

...

プロダクト構築環境の記録(AWS)

June 30, 2021

*完全な自己整理用の記事です。

プロダクトのインフラをリプレースするため、リプレース前の構築環境を記録しておく。

使用している AWS サービス #

  • Amazon Route 53
  • AWS Certificate Manager
  • Amazon CloudFront
  • Amazon Simple Storage Service (S3)
  • Amazon Elastic Load Balancing (Application Load Balancer)
  • Amazon Elastic Compute Cloud (EC2)
  • Amazon Relational Database Service (RDS)
  • AWS Lambda
  • AWS Elemental MediaConvert
  • Amazon EventBridge
  • Amazon Simple Email Service (SES)

アーキテクチャダイアグラム #

本当は diagrams.net (Drow.io) を使ってやりたいけれど省力化

...

.zshrcをメモしておくだけの記録

June 28, 2021

万が一、削除してしまった時のために .zshrc をここにメモしておく。それだけ。

保存という意味では GitHub にあげておけば良いのだが、そんなことをするまでもないと思ったのでここに記録。(私の中だと、ブログ記事よりも GitHub の方がより重要な資産を置く場所という感覚があるのですが、普通逆ですかね?)

...

GitHubからSlackへ通知させるときに叩くコマンドのメモ

June 25, 2021

作業が発生した時に毎回毎回コマンドをググっている気がしたので、ここにメモしておく。

(これは自分用のメモです。類似の良質な記事は他にいくらでもあるので、恐らくそちらをご参照いただいたほうがよいです。)

...

Serverless Framework で Firebase SDK を使用時、 "util.Long.fromValue is not a function" と出た時の対応

June 22, 2021

同事象で苦しむ人は稀と思われるので、この記録が役に立つかは不明。

発端 #

  • Serverless Framework にて AWS Lambda 上で動くコードを開発中。
  • serverless-offline にて、ローカルで起動している Firebase Local Emulator の Cloud Firestore に以下のコードを実行するとエラーが発生。

(試してはいませんが、ローカル環境で上記が発生している場合、デプロイ後の本番の Lambda 上でも同様にエラーとなるはずです。)

...

書籍学習記録 - 「テスト駆動開発」

June 4, 2021

学習記録として、記憶に残った内容をメモしておきます。

「テスト駆動開」Kent Beck / 和田 卓人 #

「テスト駆動開発」

テスト駆動開発を原点から学ぶ

本書は、自分たちのコードに自信を持って開発を続けたいプログラマ、チームリーダー向けに、テスト駆動開発(TDD)の実践方法を解説した“Test-Driven Development By Example"の日本語版です。テスト駆動開発の考案者である Kent Beck 自身によって書かれた原典を、日本におけるテスト駆動開発の第一人者である和田卓人氏が訳しました。 テスト駆動開発とは単にテスト自動化を行うことではなく、ユニットテストとリファクタリングを両輪とした小さいサイクルを回すことで不確実性を制御し、不断の設計進化を可能にする手法であることを、実例を通して学ぶことができます。

...

プログラミングスクールを卒業して

June 1, 2021

事後報告になってしまいましたが、昨年秋頃より通学していたプログラミングスクールを先月無事に卒業しました。

どこの学校に行っていたの? #

以前に書いた以下の記事でも記載しましたが、G’s ACADEMY(ジーズアカデミー)という学校です。

...

ブログをWordPressからHugo & GitLabに引っ越しする手順

May 23, 2021

このブログはこれまで WordPress で運用してきたのですが、今回、Hugo に乗り換えることにしました!

この記事は Hugo に乗り換えて初めて投稿する記事です!

皆さんがこの記事を読んでいるということは、無事に 引っ越しが完了したということですね!よかった!

...

JavaScriptでクラスを実現する様々な方法

May 1, 2021

JavaScript の クラス について整理しておく。

JavaScript には class 構文があるがそれは単なるシンタックスシュガーであり、class を使わずともクラスを実現することができる。

...

GoogleスプレッドシートのGoogle Apps Script(GAS​)でハマったこと

April 14, 2021

*書き殴り気味の完全な個人的メモです。

1. フロントから GAS へのリクエストの投げ方 <Content-Type 別> #

GAS はプリフライトをさばくことはできない。

  • Content-Type application/json -> アウト
  • Content-Type x-www-form-urlencoded -> オーケー
  • Content-Type text/plain -> オーケー

1-1. Content-Type が application/json だと CORS でアウト #

const postReservation = async (name, email) => {
  const endPoint = 'https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/exec';
  const res = await fetch(endPoint, {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ name, email }),
  });
  if (res.ok) console.log('okです!'); // しかし残念ながらokになることはありません。
};

1-2. Content-Type が x-www-form-urlencoded だと オーケー #

const postReservation = async (name, email) => {
  const endPoint = 'https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/exec';
  const res = await fetch(endPoint, {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: `name=${name}&email=${email}`,
  });
  if (res.ok) console.log('okです!'); // okですね。
};

1-3. Content-Type が text/plain でも オーケー #

const postReservation = async (name, email) => {
  const endPoint = 'https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/exec';
  const res = await fetch(endPoint, {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'text/plain',
    },
    body: `${name}&&&${email}`,
  });
  if (res.ok) console.log('okです!'); // okですね。
};

2. GAS でのフロントからのリクエストの受け取り方 <Content-Type 別> #

2-1. application/json の場合(ただし CORS に引っかかるので実質機能しない) #

const doPost = (e) => {
  const jsonString = e.postData.getDataAsString();
  const data = JSON.parse(jsonString);
  const { name, email } = data;
  // 以降処理は続く...
};

2-2. x-www-form-urlencoded の場合 #

const doPost = (e) => {
  const name = e.parameters['name'][0];
  const email = e.parameters['email'][0];
  // 以降処理は続く...
};

2-3. text/plain の場合 #

const doPost = (e) => {
  let text = e.postData.getDataAsString();
  const [name, email] = text.split('&&&'); // フロントからリクエスト送る時に区切り文字を何にしているかによります
  // 以降処理は続く...
};

3. GAS からフロントへのリクエストの返し方 #

GAS からのレスポンスは、成功だと 302 FOUND が返り、失敗だと 200 OK が返る。

...