11月2週(実績)

土曜:7h

  • 今日は技術の選定をしながら使用技術が決まっているfirebaseでの認証とメニューの作成をする
  • データベース をどうしようか悩んだが、今回はクライアント(Nuxt.js)の実装力を鍛えることが目的のためfirebaseのCloud firestoreを使おうと思う

    Cloudfirestoreの設定

  • 以下より、環境に合わせた権限の設定を行う Cloud Firestore を使ってみる  |  Firebase
// テストモード 
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}
//ロックモード
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}
//認証必須
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

firebaseの初期化処理の記述

  • firebase上でアプリケーションを作成したらAPIキーをメモする
  • Nuxtアプリ内のpluginsフォルダにfirebase.jsを作成する(pluginsフォルダの内容はアプリケーション初期化時に読み込まれる
import firebase from 'firebase/app'
import 'firebase/firestore'
import 'firebase/auth'

export default (_context, inject) => {
  let fireApp
  if (!firebase.apps.length) {
    fireApp = firebase.initializeApp({
      aapiKey: 'hoge',
      authDomain: 'hoge',
      databaseURL: 'hoge',
      projectId: 'hoge',
      storageBucket: 'hoge',
      messagingSenderId: 'hoge',
      appId: 'hoge',
      measurementId: 'hoge'
    })
  } else {
    fireApp = firebase.app()
  }
  inject('fireApp', fireApp)
}
  • これでNuxt内でthis.$fireAppとしてfirebaseアプリにアクセスできる
  • 土曜日の成果としては以下の通り
    • 仕様に対するアプローチや仕様技術をぼんやりと決めた
    • firebase上にアプリケーションを作成
    • Cloud firestoreの初期化
    • メニューの作成

日曜:6h

  • TypeScript化が結構面倒。。。しかし、型推論の良さを最近実感してきたのでちょっとずつ理解をしていく。
  • プロパティを初期化しないことによるエラーや想定していない事象が多いのでプロパティを初期化することを意識する。
  • firebaseのTimeStampの仕様変更に伴う対応

qiita.com - actionをpageなりorganismsから呼ぶなりするときにモジュールの登録をしていないことで呼べないということでハマった。actionを作ったらstore/index.tsにて以下のようにモジュールの登録を行う。 f:id:yosuke0517:20191110201912j:plain

月曜:10h

排他制御(楽観的ロック・悲観的ロックについて)

楽観的ロック

  • 更新対象のデータがデータ取得時と同じ状態であることを確認してから更新することで、データの整合性を保証する方式。めったなことでは他者との同時更新は起きないであろう、という楽観的な前提の排他制御

悲観的ロック

  • 更新対象のデータを取得する際にロックをかけることで、他のトランザクションから更新されないようにする方式。他者が同じデータに頻繁に変更を加えるであろう、という悲観的な前提の排他制御
  • 悲観ロックでは、ロックの解放漏れがあると、いつまで経っても他者が操作できないということに繋がるため、データ更新後はロックの解放を必ず行うこと。また、確実にロックを解放するのは難しいという特性も持っている。例えば処理中に、
  • Webアプリケーションでブラウザの×ボタンが押された
  • Webブラウザが強制シャットダウンした
  • 操作しているPCを強制シャットダウンした
  • 等が発生すると、場合によってはロックしたままの状態となってしまう。これら全てをアプリケーションの設計で制御するのは困難なため、悲観ロックを採用する場合は、

  • 管理者であればロックを解放できる機能を設ける

  • ロックしているユーザであれば、ロックを再取得できるようにする
  • ロックしているユーザのセッションタイムアウトのタイミングで、そのユーザがロックしている全てのデータのロックを解放する
  • 長時間ロックされているデータはロック解放するような機能を設ける

  • 等の仕組みを設ける等、何らかの対応策を用意しておく必要がある。

参考:https://qiita.com/NagaokaKenichi/items/73040df85b7bd4e9ecfc

リファクタリング

  • 実装例で提示されたコード(固有情報は一部マスクしてます)なんですが、...なんか汚いと思うのは私だけ??
  • リファクタリングしてみましたが、皆さんならどうしますか?javascriptの基礎がわかってれば理解できると思うので、箸休め的な感じで見てやってください。

  • 提示されたコード

async show() {
    const { dateRange, displayFlag } = this.form
    const loading = this.$loading(this.loadingOptions)
    this.clearErrorMessages()
    await this.$store
      .dispatch('hoge/count', {
        dateRange,
        displayFlag
      } as CountFilter)
      .then(() => {
        this.$store
          .dispatch('hoge/search', {
            dateRange,
            displayFlag,
            pageNumber: 1
          } as HogeListFilter)
          .then(() => {
            this.refreshGridData()
          })
          .catch((error: AxiosError) => {
            this.addError(error)
          })
      })
      .catch((error: AxiosError) => {
        this.addError(error)
      })
      .finally(() => {
        loading.close()
      })
  }

以下のようにリファクタリング。動作確認などはしてないので下が動くかはわからないけど...

async show() {
    const { dateRange, displayFlag } = this.form
    const loading = this.$loading(this.loadingOptions)
    this.clearErrorMessages()
    try{
      await Promise.all([
        this.$store.dispatch('hoge/count', {
          dateRange,
          displayFlag } as CountFilter),
        this.$store.dispatch('hogeList/search', {
          dateRange,
          displayFlag,
          pageNumber: 1 } as HogeListFilter),
        this.refreshGridData()
    ])
    } catch {((error: AxiosError) => {
        this.addError(error)})
    } finally{(() => {
        loading.close()})
    }
    
  • 明日はNuxt,TypeScript,firebaseでのユーザ作成・ログイン処理を書く。ネタ元以下。

blog.h-sakano.dev

火曜:10.5h

環境に合わせてURLを変えたい時なんかはcross-envを使う。

envファイルでこんな感じで宣言

module.exports = {
 dAuthLoginUrl: 'http://localhost:9000',
 apiBaseUrl: 'http://localhost:8080',
 kngnAnalysisUrl: 'https://qiita.com/TakahiRoyte/items/c152ad8baa191ed1f8ae'
}

nuxt.config.tsでexportして使えるようにする

const environment = process.env.NODE_ENV || 'development';
const envSet = require(`./env.${environment}.js`)

module.exports = {

 env: envSet

}

実際に使うとき

window.open(process.env.kngnAnalysisUrl)こんな感じ

参考以下

qiita.com

水曜:9h

  • Firebaseのユーザ登録(email&password認証)で成功した際に返却される値(const responseとした場合)
  • user

    • uid
    • email
    • displayName
  • メモ

    • ログイン処理でルートに飛ばないのでログイン処理完了用のメソッドを作るか、フラグを持ってWatchで強制的に遷移させる

木曜:9h

  • 画面作成の際にpages配下に@Component({})がないがためにプロパティにアクセスできなかったり、コンポーネントの名前がおかしなことになったりした。
  • コンポーネントを出力させたいときは@Component({})を忘れずに。以下みたいになるぞ。 f:id:yosuke0517:20191114231903p:plain

もう一つ

  • storeのindex.tsについて。最終的に機能名のフォルダ名でexportするワケだけど以下のようにModule名とexport名を合わせないといけない。 f:id:yosuke0517:20191114235810j:plain

金曜:5h

Nuxt.js + TypeScriptのアクションの呼び方(フォルダ構成でハマりunknown action

  • pagesやコンポーネントからactionを呼ぶときに使ってるこの指定表現。フォルダ階層で指定するのかと思ったらモジュール階層だった。
this.$store.dispatch('hoge-huga/upload', this.files)

どういうことか

  • 例えば以下の構成でactionに定義しているuploadアクションを呼びたいとき
//フォルダ構成
store
┗hoge-huga
 ┗actions.ts  //uploadアクションが定義されているとする。
 ┗index.ts
 ┗getters.ts
 ┗mutations.ts
  • 最初にも出てきたようにhoge-hugaフォルダは以下のactionにあるuploadを呼ぶ。という意味で以下のように記述していた。が、unknown actionと言われエラーとなる。
//このようにフォルダ階層で指定していたらactionへ到達せずエラーとなる
this.$store.dispatch('hoge-huga/upload', this.files)

え、じゃあどこ指定すればいいの?

  • store/hoge-huga/index.tsの一番下をを見てみると...
export default hoge_huga
  • アンダースコアにしてる...ややこしい。なんでこうしたんだっけ??
  • ハイフンにすればいいじゃんと思ったらハイフンは使えないようだ。ハイフンで単語が区切られてエラーになる。

  • なので現状はthis.$store.dispatch('hoge-huga/upload', this.files)と指定して実装を続けているが次からはフォルダを作るときはハイフン(-)じゃなくてアンスコ(_)で繋ぐのが無難。

週次報告

  • 目標勉強時間:70h
  • 勉強時間:56.5h
  • 目標との乖離:-166.75h
  • 何を得たか:nuxt.js + TypeScriptの基礎
  • 何が必要か:nuxt.js + typescriptの基礎と応用
  • 来週の目標:nuxt.js + typescript のインプットとアウトプットを続ける