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+Firebaseで作るサーバーレスアプリケーション/Create ser...
Search
Kota Nonaka
October 24, 2018
Programming
1
1.1k
TypeScript+Firebaseで作るサーバーレスアプリケーション/Create serverless app with TypeScript + Firebase
ゆるはち .it Vol.3 「 JavaScriptについてゆるく話す」で使用した資料です。
Kota Nonaka
October 24, 2018
Tweet
Share
More Decks by Kota Nonaka
See All by Kota Nonaka
このあとからできる アクセシビリティ向上 / Accessibility improvements that can be made after this
uutarou10
0
350
React Nativeと半年間戦ってわかったコト / What I learned after fighting React Native for half a year
uutarou10
1
240
GatsbyでPWAやってみた / Tried PWA using Gatsby
uutarou10
1
410
CSS ド入門ハンズオン/CSS beginner's hands-on
uutarou10
2
78
初心者による初心者のためのKubernetesハンズオン
uutarou10
4
3.2k
Other Decks in Programming
See All in Programming
AWS Organizations で実現する、 マルチ AWS アカウントのルートユーザー管理からの脱却
atpons
0
130
ISUCON14公式反省会LT: 社内ISUCONの話
astj
PRO
0
180
CI改善もDatadogとともに
taumu
0
110
データの整合性を保つ非同期処理アーキテクチャパターン / Async Architecture Patterns
mokuo
41
15k
さいきょうのレイヤードアーキテクチャについて考えてみた
yahiru
3
730
CNCF Project の作者が考えている OSS の運営
utam0k
5
690
自分ひとりから始められる生産性向上の取り組み #でぃーぷらすオオサカ
irof
8
2.6k
2,500万ユーザーを支えるSREチームの6年間のスクラムのカイゼン
honmarkhunt
6
5.1k
TokyoR116_BeginnersSession1_環境構築
kotatyamtema
0
110
sappoRo.R #12 初心者セッション
kosugitti
0
230
Honoをフロントエンドで使う 3つのやり方
yusukebe
4
2.1k
Amazon S3 TablesとAmazon S3 Metadataを触ってみた / 20250201-jawsug-tochigi-s3tables-s3metadata
kasacchiful
0
100
Featured
See All Featured
BBQ
matthewcrist
86
9.5k
Scaling GitHub
holman
459
140k
Designing for humans not robots
tammielis
250
25k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Building Applications with DynamoDB
mza
93
6.2k
Automating Front-end Workflow
addyosmani
1367
200k
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
The Invisible Side of Design
smashingmag
299
50k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.2k
Docker and Python
trallard
44
3.3k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Transcript
TypeScript + Firebaseで作る サーバーレス アプリケーション 2018年10月24日(水) ゆるはち.it Vol.3 Kota Nonaka
(@uutarou10)
今日やること • Firebaseの機能紹介 • TypeScript + Firebase Webアプリケーションコード解説 !2
Firebaseについて !3
Firebase • モバイルアプリ用のバックエンドを 提供するプラットフォーム(mBaaS) • 現在はGoogleが提供している • iOS/Android/UnityなどのSDKが提供 実は、Web用のJavaScript SDKも!
!4
Firebaseが提供するサービス 現在はBeta版含め18個のサービスが提供されている (Web SDKで利用できるサービスは9個) !5 • Cloud Firestore • Cloud
Functions • Authentication • Hosting • Cloud Storage • Realtime Database • Predictions • Cloud Messaging • Dynamic Links
Firestore / Realtime Database • どちらもNoSQLデータベース • リアルタイム更新やオフライン状態での更新などにも対応 • Realtime
Databaseの進化版がFirestore • 今回のサンプルアプリではFirestoreを使用 !6
Authentication • ユーザー認証のあれこれをやってくれるサービス • 様々な認証方法 • メールアドレス/パスワード認証 • Google/GitHub/Twitter/Facebookなどを用いたSNS認証 •
SMS認証機能 • Firebaseの各サービスへの権限管理にも使われる !7
Hosting • 静的なWebサイトをホスティングできる • GoogleのCDNが使われる • Let’s Encryptを用いた無料SSL • もちろん独自ドメインも使用可能
• デプロイはCLIツールからワンコマンドで可能 !8
料金 • https://firebase.google.com/pricing/ • 趣味で使う程度の規模ならば無料で使用可能 !9
実際のコードを見てみる !10
サンプルアプリを作った • 2チャンネルクローン? 「8ちゃんねる」 • 八王子の8、ゆるはちの8です… • Reactを用いたSPA && 言語はTypeScript
• わかりづらかったらごめんなさい • Firebase Authentication と Firestore を使用 • https://eight-channel.firebaseapp.com • https://github.com/uutarou10/eight-channel !11
ざっくりこんな要件 • スレッド作成/新規投稿はGoogle ログインが必要 • 閲覧は全ユーザーが可能 • (表示されていないけど) 投稿ユーザーを記録する !12
ディレクトリ構成 • firebase.json / firestore.indexes.json / firestore.rules Firebase関係の設定ファイルたち FirebaseのCLIツールで生成される •
src アプリケーション本体のソースコード !13
初期化処理 !14
初期化 • コンソール画面から取得したAPI Keyなどを専用のメソッドに渡す。 !15
初期化 export const app = firebase.initializeApp({ apiKey: process.env.REACT_APP_API_KEY, authDomain: process.env.REACT_APP_AUTH_DOMAIN,
databaseURL: process.env.REACT_APP_DB_URL, messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID, projectId: process.env.REACT_APP_PROJECT_ID, storageBucket: process.env.REACT_APP_STORAGE_BUCKET, }); !16 src/util/firebase.ts 環境変数に先ほどの値が入っている
Firestore !17
データ構造 !18 threadsというcollection
データ構造 !19 それぞれのスレッドがdocumentとして 格納されている
データ構造 !20 それぞれのthreadsのドキュメント下に postsという別のcollection
データ構造 !21 投稿の内容がkey-valueの形で 入っている
コードから扱う - Read export default { getList: async () =>
{ const querySnapshot = await db.collection('threads').orderBy('createdAt', 'desc').get(); const result: Thread[] = []; querySnapshot.forEach(thread => { result.push(createThreadByDocumentSnapshot(thread)); }); return result; }, !22 src/repository/thread.ts
コードから扱う - Read const createThreadByDocumentSnapshot = (snapShot:firebase.firestore.DocumentSnapshot): Thread => {
const data = snapShot.data() as firebase.firestore.DocumentData; return { id: snapShot.id, title: data.title, uid: data.uid, createdAt: data.createdAt.toDate() }; }; !23 src/repository/thread.ts dataメソッドを呼び出すと 値を取得できる
コードから扱う - Write create: async (title: string, uid: string) =>
{ const docRef = await db.collection('threads').add({ title, uid, createdAt: firebase.firestore.FieldValue.serverTimestamp() }); return createThreadByDocumentSnapshot(await docRef.get()); } !24 src/repository/thread.ts
ところで • 「クライアントから直接DBが触れるのはわかった。」 • 「何でも誰でも書き放題、読み放題じゃない?」 • 「想定していないデータを突っ込む事ができてしまうのでは?」 !25
セキュリティールール • JavaScript風のDSLで操作を実行できる条件を指定する • これを活用して… • 必須カラムを指定 • 権限を設定 •
発行できるクエリに制限をかける !26
セキュリティールール service cloud.firestore { match /databases/{database}/documents { match /threads/{thread}{ allow
read; allow create: if request.auth.uid == request.resource.data.uid && request.resource.data.keys().hasAll(['title', 'createdAt', 'uid']); match /posts/{post} { allow read; allow create: if request.auth.uid == request.resource.data.uid && request.resource.data.keys().hasAll(['name', 'body', 'uid', 'createdAt']); } } } } !27 firestore.rules
セキュリティールール service cloud.firestore { match /databases/{database}/documents { match /threads/{thread}{ allow
read; allow create: if request.auth.uid == request.resource.data.uid && request.resource.data.keys().hasAll(['title', 'createdAt', 'uid']); match /posts/{post} { allow read; allow create: if request.auth.uid == request.resource.data.uid && request.resource.data.keys().hasAll(['name', 'body', 'uid', 'createdAt']); } } } } !28 firestore.rules title, createdAt, uidを持っている事 requestしてきたユーザーのuidがリクエストの uidと一致する事
Authentication !29
Authentication • 事前にConsoleから使いたい認証方法をオンに設定しておく • Google認証やパスワード認証の場合はほとんどオンにするだけ • Google以外のSNS認証の場合はアクセストークンなどを 別途取得する必要あり !30
!31
認証を行う export const signInWithGoogle = () => { const provider
= new firebase.auth.GoogleAuthProvider(); auth.signInWithRedirect(provider); }; !32 src/util/firebase.ts
認証を行う • プロバイダーとしてGoogleを指定して、 signInWithRedirectを呼ぶだけ。 • これだけでRedirectした上で認証して元のページに戻ってくる !33
ハンドラー auth.onAuthStateChanged(user => { store.dispatch(authStateChanged(user)); }); !34 src/App.tsx
ハンドラー • 認証状態が変化(ログイン/ログアウト)するとonAuthStateChangedで 設定したハンドラーにユーザーが渡されて呼ばれる • 今回はRedux(状態管理のライブラリ)にユーザーを投げて保持しておく • Google認証の場合はGoogleのAPIを使うためのtokenを取得できる • Googleのサービスと連携したアプリケーションの開発も可
!35
まとめ • FirebaseはWebアプリでも超使える! • 素早く何かを作りたい/プロトタイプ作りという用途には最適 • Authのハンドラーなどやや癖がある部分もあるので、Firebaseに依存しないよ うにするには”うまいことする力”が必要だと思った • もしくはFirebaseべったりなコードなるのを覚悟する
• セキュリティールールには気をつけないといけない • フロントエンドの勉強をするのに最適だと個人的には感じました。 !36
JavaScript要素が少なくてゴメンナサイ おしまい !37