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.2k
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
390
React Nativeと半年間戦ってわかったコト / What I learned after fighting React Native for half a year
uutarou10
1
250
GatsbyでPWAやってみた / Tried PWA using Gatsby
uutarou10
1
420
CSS ド入門ハンズオン/CSS beginner's hands-on
uutarou10
2
83
初心者による初心者のためのKubernetesハンズオン
uutarou10
4
3.3k
Other Decks in Programming
See All in Programming
TROCCO×dbtで実現する人にもAIにもやさしいデータ基盤
nealle
0
390
OSS開発者という働き方
andpad
5
1.6k
オープンセミナー2025@広島「君はどこで動かすか?」アンケート結果
satoshi256kbyte
0
230
レガシープロジェクトで最大限AIの恩恵を受けられるようClaude Codeを利用する
tk1351
4
1.5k
さようなら Date。 ようこそTemporal! 3年間先行利用して得られた知見の共有
8beeeaaat
0
200
Google I/O recap web編 大分Web祭り2025
kponda
0
2.9k
go test -json そして testing.T.Attr / Kyoto.go #63
utgwkk
1
200
CloudflareのChat Agent Starter Kitで簡単!AIチャットボット構築
syumai
1
320
AI時代のUIはどこへ行く?
yusukebe
9
4.7k
兎に角、コードレビュー
mitohato14
0
170
Langfuseと歩む生成AI活用推進
licux
3
320
AIコーディングAgentとの向き合い方
eycjur
0
250
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.5k
Designing for Performance
lara
610
69k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
131
19k
Speed Design
sergeychernyshev
32
1.1k
Facilitating Awesome Meetings
lara
55
6.5k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
111
20k
Into the Great Unknown - MozCon
thekraken
40
2k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.5k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Done Done
chrislema
185
16k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
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