Firebase ユーザ認証機能を利用する

今回もこちらの続き。

今回も参考はこちら。
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>

以上で、基本的な手習いは終わりです。

https://titanicfire-d43cd.web.app/