Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TypeScript+Firebaseで作るサーバーレスアプリケーション/Create ser...

Kota Nonaka
October 24, 2018

TypeScript+Firebaseで作るサーバーレスアプリケーション/Create serverless app with TypeScript + Firebase

ゆるはち .it Vol.3 「 JavaScriptについてゆるく話す」で使用した資料です。

Kota Nonaka

October 24, 2018
Tweet

More Decks by Kota Nonaka

Other Decks in Programming

Transcript

  1. Firebaseが提供するサービス 現在はBeta版含め18個のサービスが提供されている
 (Web SDKで利用できるサービスは9個) !5 • Cloud Firestore • Cloud

    Functions • Authentication • Hosting • Cloud Storage • Realtime Database • Predictions • Cloud Messaging • Dynamic Links
  2. サンプルアプリを作った • 2チャンネルクローン? 「8ちゃんねる」 • 八王子の8、ゆるはちの8です… • Reactを用いたSPA && 言語はTypeScript

    • わかりづらかったらごめんなさい • Firebase Authentication と Firestore を使用 • https://eight-channel.firebaseapp.com • https://github.com/uutarou10/eight-channel !11
  3. 初期化 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 環境変数に先ほどの値が入っている
  4. コードから扱う - 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
  5. コードから扱う - 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メソッドを呼び出すと 値を取得できる
  6. コードから扱う - 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
  7. セキュリティールール 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
  8. セキュリティールール 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と一致する事
  9. !31

  10. 認証を行う export const signInWithGoogle = () => { const provider

    = new firebase.auth.GoogleAuthProvider(); auth.signInWithRedirect(provider); }; !32 src/util/firebase.ts