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
370
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
81
初心者による初心者のためのKubernetesハンズオン
uutarou10
4
3.2k
Other Decks in Programming
See All in Programming
iOSアプリ開発で 関数型プログラミングを実現する The Composable Architectureの紹介
yimajo
2
200
人には人それぞれのサービス層がある
shimabox
3
660
Go Modules: From Basics to Beyond / Go Modulesの基本とその先へ
kuro_kurorrr
0
110
Webからモバイルへ Vue.js × Capacitor 活用事例
naokihaba
0
500
The Evolution of Enterprise Java with Jakarta EE 11 and Beyond
ivargrimstad
1
570
Datadog RUM 本番導入までの道
shinter61
1
240
Javaに鉄道指向プログラミング (Railway Oriented Pro gramming) のエッセンスを取り入れる/Bringing the Essence of Railway-Oriented Programming to Java
cocet33000
2
530
UPDATEがシステムを複雑にする? イミュータブルデータモデルのすすめ
shimomura
1
520
Devinで実践する!AIエージェントと協働する開発組織の作り方
masahiro_nishimi
6
3k
レガシーシステムの機能調査・開発におけるAI利活用
takuya_ohtonari
0
580
Spring gRPC で始める gRPC 入門 / Introduction to gRPC with Spring gRPC
mackey0225
2
480
「ElixirでIoT!!」のこれまでとこれから
takasehideki
0
350
Featured
See All Featured
Typedesign – Prime Four
hannesfritz
42
2.7k
Building Applications with DynamoDB
mza
95
6.4k
Reflections from 52 weeks, 52 projects
jeffersonlam
349
20k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
123
52k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
4
130
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Mobile First: as difficult as doing things right
swwweet
223
9.6k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
14
1.5k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.8k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
48
5.4k
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