Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TypeScriptから使いやすいFirestore-simpleを紹介します(2020年版)
Search
Kenta Kase
June 26, 2020
Programming
2.2k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TypeScriptから使いやすいFirestore-simpleを紹介します(2020年版)
2020/06/26 Firebase Realtime Meetup
https://firebase-community.connpass.com/event/175985/
Kenta Kase
June 26, 2020
More Decks by Kenta Kase
See All by Kenta Kase
GitHub Actionsオタクによるセルフホストランナーのアーキテクチャ解説
kesin11
0
420
GitHubの新機能とGHESのリリースノートの対応をまとめ続けている話
kesin11
0
210
CircleCIでLayer Cachingを使わずにdocker buildを高速化する
kesin11
3
2.3k
CI/CDのボトルネックを把握できていますか?BigQueryでビルド情報ダッシュボードを構築した話
kesin11
7
11k
GitHub Actionsが他のCIサービスと比較してできることできないこと
kesin11
1
1.7k
iOSアプリのリジェクトリスクを早期に発見するための取り組み
kesin11
4
18k
BitriseでFastlane/Gradleプラグインの統合テスト
kesin11
0
3.5k
Firebase Test Labの紹介
kesin11
4
1.6k
Cloud Functions × BigQuery
kesin11
5
2.4k
Other Decks in Programming
See All in Programming
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
280
AIと壁打ちしながら進めるコスト管理
fufuhu
2
1.9k
Can LLMs Replicate 4 Years of Compose Migration? Exploring the boundaries of automation with 279 XML files from a real product
makun
0
130
GKE アップグレード前に知っておきたい Blue/Green と PDB の関係
stkk
0
130
Press start. Python's next generation.
willingc
PRO
3
300
不幸な GC
chencmd
0
870
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
310
iOS開発×AI駆動開発 〜最近使って便利だったスキルの話〜
nogu66
0
140
Building an Out-of-Order CPU
latte72
0
430
Go を使い始めて 2 ヶ月の学び / My first two months with Go
contour_gara
0
410
ソフトウェアラスタライザ
fadis
1
770
PyConJP2026_wat_Python × Signal Processing: How to Draw Pictures with Sound Using Spectrogram Art
wat
0
650
Featured
See All Featured
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
400
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Heart Work Chapter 1 - Part 1
lfama
PRO
8
36k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
490
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
So, you think you're a good person
axbom
PRO
2
2.1k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
4.6k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
290
Transcript
TypeScriptから使いやすいFirestore-simpleを紹介します(2020年版) Firebase Realtime Meetup (2020/06/26) @Kesin11
⾃⼰紹介 @Kesin11 (GitHub/Twitter) 本業 組織横断でテストやCI/CDの調査・サポートなど (おそらく普通よりは)CIマニアの気がある Firebaseはプライベート開発がメイン 2019年のアドベントカレンダーでエミュレータを使ったテストの書き⽅を紹介 Firebase Emulator
Suiteをフル活⽤してTDDで開発しよう 2
はじめに この発表はFirestoreの機能は⼀通り知っている前提で話します 質問はYouTubeのコメントにお願いします! 発表中に答えきれなかったらTwitterの#FJUGあたりで回答するかも? 放送後はFJUGのSlackで質問して頂ければ回答できます 3
TypeScriptでFirestoreのコード書くときどんな感じのコードになりますか?
多分こんな感じ? type User = { name: string, age: number, }
const alice: User = { name: 'alice', age: 20 } const docRef = await firestore.collection('users').add(alice) const snapshot = await firestore.collection('users').doc(docRef.id).get() const user = snapshot.data() as User // ここでキャストして型を付ける 毎回collectionを書くのが⾯倒くさい 毎回data()を書くのが⾯倒くさい 毎回キャストで型を付けるのが⾯倒くさい 気軽にキャストしていくのは型ミスに繋がる 5
⾃分でUserCollectionクラスを作ろう class UserCollection { collection: CollectionReference constructor (firestore: Firestore) {
this.collection = firestore.collection('users') } async fetch (userId: string) { const snapshot = await this.collection.doc(userId).get() return snapshot.data() as User } } const userCollection = new UserCollection(firestore) // id='alice' を渡すだけ const user = await userCollection.fetch('alice') 6
⾃分でUserCollectionクラスを作ろう 初期の頃に⾃分が取っていたアプローチ collectionやdata()を毎回書かなくて済む キャストする場所が集約される コレクション毎に似たようなクラスを作る必要がある? 汎⽤化したクラスを作れば全コレクションで使いまわせそう Firebaseプロジェクト毎に汎⽤化したクラスをコピペで持ってくる? -> ライブラリ化しよう 7
Firestore-simple https://github.com/Kesin11/Firestore-simple
Firestore-simpleの思想 . 冗⻑なコードを省く . 強⼒な型推論と補完 . 素のFirestoreのAPIから乖離しすぎない . 間違いを起こしやすい機能へのサポート 9
1. 冗⻑なコードを省く
サンプルケース: FirestoreとTypeScript側でキー名や型が微妙に違う場合 Firestore側 /users : { name: string, age: number,
created_at: Timestamp } TypeScript側 User: { name: string, age: number, createdAt: Date } こういうケース、たまにありませんか? (むしろ皆さんが普段どうやっているのか知りたい) Firestore-simpleはこういう処理を上⼿く実現できます 11
素のFirestoreで書く場合 type User = { name: string, age: number, createdAt:
Date, // js のDate 型で扱いたい } const snapshot = await firestore.collection('users').doc(docRef.id).get() const data = snapshot.data() if (!data) return const user = { name: data.name, age: data.age, createdAt: data.created_at.toDate() // キー名を変換しつつ、Date 型に変換 } as User // 型を揃えたのでここでキャスト 12
Firestore-simpleで書いた場合 ライブコーディングします
Firestore-simpleで書いた場合 type User = { // id は必須プロパティ id: string,
name: string, age: number, createdAt: Date, } type UserFirestore = { name: string, age: number, created_at: Date, } const firestoreSimple = new FirestoreSimple(firestore) const userCollection = firestoreSimple.collection<User, UserFirestore>({ path: 'users', decode: (doc) => { return { id: doc.id, name: doc.name, age: doc.age, createdAt: doc.created_at.toDate() } } }) const user = await userCollection.fetch('alice') // => { id: 'alice', name: 'alice', // => age: 20, createdAt: 2020-06-20T13:12:54.816Z } 14
Firestore-simpleで書いた場合 collectionのpathを指定するのは⼀度だけ fetchした結果にUser型が⾃動で付く Firestore -> js での変換処理(decode)を書くのも⼀度だけ decode: (doc) =>
{} の中で doc も型推論されているので補完が効く(今回は 詳しい説明は省略) 逆⽅向のjs -> Firestoreの変換は encode: (obj) => {} (今回は省略) 型に id を必須にしているのは data() をなくしたゆえの制約 id と他のプロパティを同じようにアクセス可能にするため 先の例: user.id (FirestoreのdocumentId), user.name , user.age 15
その他よく使うと思われる機能のショートハンド fetchAll bulkAdd , bulkSet , bulkDelete batchによる⼀括更新処理のラッパー // batch
でset await userCollection.bulkSet([ { id: 'alice', name: 'alice', age: 20 }, { id: 'bob', name: 'bob', age: 22 }, ]) // colletion の全ドキュメントを取得 const users: User[] = await userCollection.fetchAll() // batch でdelete await userCollection.bulkDelete(users.map((user) => user.id)) 16
2. 強⼒な型推論と補完
現代ではwithConverterを使うという⼿がある data() の結果に型が付く。Firestore <-> jsの変換も可能 Firestore-simpleの開発を始めた2018年頃にはなかった const userConverter = {
toFirestore (user: User): FirebaseFirestore.DocumentData { return { name: user.name, age: user.age, created_at: user.createdAt } }, fromFirestore ( data: FirebaseFirestore.DocumentData): User { return { name: data.name, age: data.age, createdAt: data.created_at.toDate() } } } const userCollection = firestore.collection('users').withConverter(userConverter) await userCollection.doc('alice').set({ name: 'alice', age: 20, createdAt: new Date() }) const snapshot = await userCollection.doc('alice').get() const user: User | undefined = snapshot.data() 18
Firestoreを扱う上でバグが起きやすいのは? (個⼈的には)キー名のtypoという凡ミスが多い docRef.update({ nama: 'bob' }) collection('user').where('aga', '>=', '20') これらはwithConverterでは防ぐことができない
withConverterを通したとしても update や where はキー名までチェックしてくれない 19
Firestore-simpleでは型から抽出されるキー名で補完が可能 ライブコーディングでお⾒せします SpeakerDeckで⾒てる⽅は過去記事のGIFアニメをどうぞ TypeScriptからFirestoreを使いやすくするfirestore-simple v4をリリースしました
3. 素のFirestoreのAPIから乖離しすぎない
ActiveRecord⾵にはしない // 擬似コードです const user = new User user.name =
'alice' user.age = 20 await user.save() // ここでDB に書き込まれる const alice = await User.findBy({ name: 'alice') // DB からデータ取得 素のFirestoreと使い⽅がかなり異なる 何かエラーが起きた場合にユーザーがデバッグするのが⼤変になりそう Firestoreのアップデートに追従して機能追加していくのも⼤変そう 22
外しやすいライブラリを⽬指す あくまでFirestoreの補助 使い⽅を⼤きく変えるライブラリは外しにくくなる 外しにくい=採⽤しにくい 個⼈的なポリシー jsでまだドラフト中の新しい構⽂は使わない(デコレータとか) そもそもFirestoreがもっと便利になれば⾃作して⾃分が使う理由もなくなる withConverterが来たときは開発をやめるか⼀瞬悩みましたが、⾃分にとってはまだ 代替に⾄るものではなかった 23
4. 間違いを起こしやすい機能へのサポート batch transaction
batch const userCollectionRef = firestore.collection('users') const batch = firestore.batch() batch.set(userCollectionRef.doc('alice'),
{ name: 'alice', age: 20 }) batch.set(userCollectionRef.doc('bob'), { name: 'bob', age: 22 }) await batch.commit() 個⼈的に気に⼊らない点 transactionと挙動が似ているのに、runTransactionとAPIが全く異なる set, update, deleteの使い⽅が普通と異なる addが存在しない doc() とidを空にすると裏でランダム値を⼊れてくれるのでaddは実現可能 なぜ⽤意してくれない・・・ 25
Firestore-simpleによるbatchのサポート 単に配列を⼀括処理したい場合は bulkAdd , bulkSet , bulkdDelete runTransactionと同じように書ける runBatch も⽤意
await firestoreSimple.runBatch(async (_batch) => { await userCollection.set({ id: 'alice', name: 'alice', age: 20 }) await userCollection.set({ id: 'bob', name: 'bob', age: 20 }) await userCollection.add({ name: 'random', age: 20 }) }) // <- runBatch を抜けるタイミングで⾃動的にbatch.commit() される runBatch の中ではsetなどはすべて⾃動的にbatch内処理として扱われる うっかりbatch外処理として実⾏してしまうミスは起きない 26
Firestore-simpleによるtransactionのサポート runTransactionもrunBatchと同じ改良がされている add, set, update, deleteは⾃動的にtransaction処理として扱われる transactionはgetも同様 ⼀部の処理だけtransaction外で⾏ってしまうという危険なミスは起きない await firestoreSimple.runTransaction(async
(_tx) => { await userCollection.fetch('alice') await userCollection.fetch('bob') await userCollection.set({ id: 'alice', name: 'alice', age: 20 }) await userCollection.set({ id: 'bob', name: 'bob', age: 22 }) }) // <- runTransaction を抜けるタイミングで⾃動的にtransaction.commit() される 27
Firestoreの新しめの機能もカバーしてます FieldValue.serverTimestamp FieldValue.increment CollectionGroup where INなど Firestore Emulator Firestore-simple⾃体のテストがemulatorで実⾏されているのでバッチリ
最近のv7のアップデート
最近のv7のアップデート Web SDKにも対応しました! v6以前とはインストール⽅法から変わりました npm i firestore-simple はDEPRECATED Admin SDK,
Cloud Function⽤ npm i @firestore-simple/admin Web SDK⽤ npm i @firestore-simple/web 30
Firestore-simpleのターゲットユーザー TypeScriptで型をちゃんと付けたい 使い⽅が素のFirestoreから⼤きく変わらない⽅が好み UIフレームワークとは疎結合にしたい Firestore層のテストを書きたい Firestore-simple⾃体のテストコードをぜひ参考に 31
今後の予定 Web SDKの⼀部機能のサポートができていないので対応したい getやonSnapshotなどWeb SDKのみ存在するオプションにまだ未対応 APIドキュメント⽣成 TypeScriptで流⾏りのドキュメント⽣成ツールを知りたい Firestoreに新機能が来たら対応したい 今年はIOがなかったのでいつ来るのだろう 32
付録1 ドキュメント https://github.com/Kesin11/Firestore-simple/blob/master/README.md サンプルコード(AdminとWebで別々にあります) https://github.com/Kesin11/Firestore- simple/tree/master/packages/admin/example https://github.com/Kesin11/Firestore- simple/tree/master/packages/web/example
付録2 過去記事 v7をリリースしたので改めてfirestore-simpleを紹介します firestore-simple v5をリリースしました TypeScriptからFirestoreを使いやすくするfirestore-simple v4をリリースしました Firestoreをもっと⼿軽に使えるfirestore-simpleがバージョン2になりました Firestoreをもっと⼿軽に使えるfirestore-simpleを作った