今回もこちらの続き。
今回も参考はこちら。
Nuxt × TypeScript でTodoListとユーザ認証を実装してFirebase Hostingにデプロイ [Tutorial – Part 5/5 – ユーザ認証の追加]
https://note.mu/tkugimot/n/n80c2e4b33bbc
で、ちょっと時間が空いてしまい、始める前に気づいたら、エラーが出ている。
This dependency was not found:
nuxt_plugin_bootstrapvue_69bcb01f in ./.nuxt/index.js
To install it, you can run: npm install --save nuxt_plugin_bootstrapvue_69bcb01f
書いてある通りnpm installしてもNot Foundと言われるだけ。
しかし、
docker-compose down
docker-compose up -d
で復旧。なんのこっちゃ。
Firebase Authentication機能の利用
手順としては、まず、package.jsonにfirebaseの記述を追加して、npm updateを実行するところから始まるのですが、ここで早速大量エラー。
概ねこんな感じ。
Can't find Python executable "python", you can set the PYTHON env variable.
Failed at the grpc@1.20.0 install script.
This is probably not a problem with npm. There is likely additional logging output above.
python・・・こっちでは使っていないはずだけどね・・・
試行錯誤色々・・・
結論としては、package.jsonへ追記するfirebaseのバージョンが、参考サイトの内容だと^5.11.1なのですが、これを^6.1.0 にすることで解消。なぜ・・・
なお、なぜこのバージョンを指定したかというと、試行錯誤の中で、ncuコマンドを知ったため、実行してみると、
# ncu
Checking /app/package.json
[====================] 21/21 100%
axios 0.18.0 → 0.19.0
nuxt 2.6.3 → 2.8.0
ts-node 8.1.0 → 8.2.0
vue-property-decorator 8.1.0 → 8.1.1
vuex-module-decorators 0.9.8 → 0.9.9
firebase ^5.11.1 → ^6.1.0
@nuxt/typescript 2.6.3 → 2.8.0
cypress 3.2.0 → 3.3.1
と表示されたため。
これにより、npm updateはできるようになったのですが、まだyarn run devではエラーになっています。
Error: Cannot find module 'bootstrap-vue/nuxt'
元々は、書籍検索のサンプルで使用されているために、組み込んでいたのですが、いずれveutifyに統一することも考えると、ここで外すことにしてしまいます。
yarn remove bootstrap-vue -S
これだけではダメで、nuxt.config.ts からも削除する必要があり、それで先ほどのエラーは解消。しかし、次は、また新たなエラー。(「あらたな」と打つと「新たなエラー」を予測変換で出してくるのウケる(ウケない))
ERROR Failed to compile with 3 errors friendly-errors 20:06:12
This dependency was not found: friendly-errors 20:06:12
* ~/store/modules/users in ./node_modules/babel-loader/lib??ref--3-0!./node_modules/ts-loader??ref--3-1!./node_modules/vuetify-loader/lib/loader.js!./node_modules/vue-loader/lib??vue-loader-options!./components/GoogleSignin.vue?vue&type=script&lang=ts&
To install it, you can run: npm install --save ~/store/modules/users friendly-errors 20:06:12
These relative modules were not found: friendly-errors 20:06:12
* ../assets/images/btn_google_signin_dark_normal_web.png in ./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--5-oneOf-1-2!./node_modules/vuetify-loader/lib/loader.js!./node_modules/vue-loader/lib??vue-loader-options!./components/GoogleSignin.vue?vue&type=style&index=0&id=08720496&scoped=true&lang=css&
* ../store/modules/userTypes in ./node_modules/babel-loader/lib??ref--3-0!./node_modules/ts-loader??ref--3-1!./node_modules/vuetify-loader/lib/loader.js!./node_modules/vue-loader/lib??vue-loader-options!./pages/login.vue?vue&type=script&lang=ts&
参考サイトでは、ログインページを作成したところで一旦表示させているのですが、その時点では、store/modules/users、store/modules/userTypesを使用していないためにエラーになります。ですので、一旦最後まで作成はしてしまいます。
また、btn_google_signin_dark_normal_web.pngがないと言われているので、
https://developers.google.com/identity/branding-guidelines?hl=ja
から入手します。しかし、また新たなエラーです。
no such file or directory, scandir '/app/node_modules/node-sass/vendor
これはnpm install node-sassで解消。ログインページが開くようになります。
サービスの設定
アプリコーディングと並行して、サービスの設定も必要です。
順番が前後しますが、plugins/firebase.tsを追加するために、FirebaseのAPIキー等の取得が必要です。
参考サイトでは、アプリを追加をクリックと書かれており、その通りなのですが、全然関係ない画面のように思われるので、ちょっと不安になります。不安に負けずに進めば必要な情報が表示されます。
ところが、それだけでは、ログインしようとすると、下記のエラーが発生します。
エラー 403: restricted_client
This app is not yet configured to make OAuth requests. To do that, set up the app’s OAuth consent screen in the Google Cloud Console.
consent screen、すなわち(今分かった!)同意画面の設定が必要です。
GCPにログインして、OAuth同意画面で、メールアドレス等を登録して、保存します。一部項目は最初から入力されていますが、保存ボタンを押せない状態になっており、メールアドレスを入力しないと保存できず、これをしないと先ほどのエラーが出る状態です。
これでやっと、認証も動くようになりました。(ログアウトがないな・・・)
bootstrapベースのpugからvuetifyへの書き換え
最後に、先ほど、bootstrapを外してしまったために、書籍検索がちゃんと表示されなくなってしまっていますので、書き換えます。見よう見まねでやったものの、いまいち綺麗に表示されていませんが、何かの役にたつと思うので、書き換え前後を置いておきます。
pages/book/index.vue 書き換え前
<template lang="pug">
section
b-container
b-row.row
b-col
b-form(@submit="onSubmit")
b-input-group(size="lg")
b-form-input(
size="sm",
class="mr-sm-2",
type="text",
placeholder="キーワードを入力してください。",
@change="handleChange"
:value="query"
)
b-button(size="sm",class="my-2 my-sm-0",type="submit") 検索する
b-col
div.cards
book-list-item(
v-for='book in books',
:key='book.id',
:book='book',
)
</template>
pages/book/index.vue 書き換え後
<template>
<div>
<form @submit.prevent="onSubmit">
<v-container>
<v-layout row wrap>
<v-flex xs8>
<v-text-field
placeholder="キーワードを入力してください。"
outline
size="sm"
class="mr-sm-2"
@change="handleChange"
:value="query"
></v-text-field>
</v-flex>
<v-flex xs4>
<v-btn round size="sm" class="my-2 my-sm-0" type="submit">
検索する</v-btn>
</v-flex>
</v-layout>
</v-container>
</form>
<div class="cards">
<div class="column">
<book-list-item v-for='book in books'
:key='book.id'
:book='book' />
</div>
</div>
</div>
</template>
BookListItem.vue 書き換え前
<template lang="pug">
b-card.mb-2.card(:title="title", :img-src='thumbnail', img-alt='Image', img-top='', tag='article', style='max-width: 20rem;')
p.card-text {{description}}
router-link(:to="'/book/books/' + id")
b-button(variant='primary') 詳細を見る
</template>
BookListItem.vue 書き換え後
<template>
<v-card>
<v-img
:src="thumbnail"
style='max-width: 20rem;'></v-img>
<v-card-title primary-title>
<div>
<h3 class="headline mb-0">{{ title }}</h3>
<div> {{ description }} </div>
</div>
</v-card-title>
<v-card-actions>
<router-link :to="'/book/books/' + id">
<v-btn variant='primary'>
詳細を見る
</v-btn>
</router-link>
</v-card-actions>
</v-card>
</template>
BookDetailItem.vue 書き換え前
<template lang="pug">
div.card
div.thumbnail
b-img(:src="thumbnail",fluid,alt="Responsive image")
div.content
h2 {{title}}
p.card-text {{description}}
</template>
BookDetailItem.vue 書き換え後
<template>
<v-card>
<v-img
:src="thumbnail"
fluid></v-img>
<v-card-title primary-title>
<div>
<h2>{{ title }}</h2>
<div> {{ description }} </div>
</div>
</v-card-title>
</v-card>
</template>
以上で、基本的な手習いは終わりです。