Firebaseを使ったGoogleアカウントのユーザー認証についてまとめました。認証はFirebase Authentication、画像のストレージはFirebase Storage、ユーザ情報はFirebase Firestoreを使っています。
目次
事前準備
認証をする前にfirebase.jsに以下の設定を書いて、Firebaseプロジェクトと連携しておきます。
・firebase.js
Google認証全体像
Firebase Authenticationを使ったGoogle認証の全体像は以下のようになります。こちらのコードは以下を参考にしています。
参考:https://github.com/FujiyamaYuta/nuxt-firebase-project
それぞれの処理をより深く理解するために、1つ1つの処理を追って自分の言葉で解説していきます。
ユーザー認証の処理を順番に実行
メソッドチェーンで順番に処理を実行していきます。
then内のいずれかでエラー(reject)が発生した場合にonRejecttedメソッドが呼び出されます。
Promise.resolve() メソッドは、引数の値でPromiseオブジェクトを返します。その値がプロミスであった場合は、そのプロミスが返されます。その値がthenable (すなわちthenメソッドを持っている場合) であれば、返されるプロミスは thenable を追跡し、その最終的な状態になります。
今回の場合は返り値がなくその後の処理もないため、①から⑦まで順番に実行して終了します。
① 認証状態の永続性をセット
setPersistenceメソッドで認証状態の永続性をセットします。
認証状態の永続性のタイプは「local」、「session」、「none」の3つがあります。詳しい説明などはこちらの公式サイトを参照ください。
認証状態の永続性は、firebase.auth().setPersistence メソッドを呼び出すことによって指定または変更できます。
② Google認証
Googleの認証を行います。
firebase.auth.GoogleAuthProvider()メソッドでGoogle認証のプロバイドを呼び出します。それを引数に firebase.auth().signInWithPopup()メソッドで認証画面のポップアップを表示します。
Google認証完了後、認証の結果のプロミスを返します。エラーコードやエラーメッセージなどはcatch内の方法で取得できるため、Google認証に失敗した時のエラーハンドリングで使うことができます。
③ ユーザー情報を取得し、オブジェクト化
Google認証の結果を元にユーザー情報を取得して、オブジェクト化します。オブジェクト化した結果のプロミスを返します。
④ アイコン画像をFirestorageに保存し、そのパスを取得
GoogleのアイコンのURLからXMLHttpRequestでアイコン画像を取得します。
xhr.responseTypeでレスポンスの方をblobに定義しています。let blob = xhr.responseで取得した画像のblobオブジェクトをblobに渡しています。
その後、Storageのuser/${userObject.uid}/image.jpgパスを用意し、そこにアイコン画像データを保存します。
getDownloadURL()メソッドで、保存したアイコン画像のURLパスを取得し、userObject.photoURLに渡しています。
つまりGoogle認証時に取得したGoogle内に保持しているアイコン画像のパスからXMLHttpRequestでアイコン画像をblobタイプで取得し、それをFirestorageに保存し、保存したURLのパスを取得しFirestoreに保存するために再度userObject.photoURLにパスを渡しているといった処理になります。
xhr.send()の処理は、「Unchecked runtime.lastError: The message port closed before a response was received.」のエラーを回避するため、特に何もなくても返信しています。
参考:https://qiita.com/noenture/items/3978f638f2ffb8ff0995
⑤ 公開可能なユーザー情報をFirestoreに登録
ユーザー情報の中でも公開可能な情報をFirestoreに登録します。createPublicObjメソッドを呼び出しpublicObjに公開可能な情報をセットし、Firestoreのusersコレクション内にuidをkeyにして登録しています。
mergeオプションをつけるとフィールドの追加をしています。
⑥ 非公開なユーザー情報をFirestoreに登録
公開可能のユーザ情報登録と同じように、非公開のユーザ情報も登録していきます。非公開情報ではメールやトークンが登録されています。
⑦ ローカルストレージに保持するユーザー情報をセット
Firestoreに保存した公開可能なユーザ情報から「アイコン画像パス」、「uid」、「トークン」、「表示名」を取得し、Local Storageにセットして、認証完了です。
ユーザーがログイン状態になり、更新情報を画面に反映させるためにリロードしています。
エラーハンドリング
ユーザー認証のメソッドチェーン内でエラーが発生した場合は、catch内のonRejecttedメソッドが呼び出され、ログインに失敗するようハンドリングしています。
参考:
https://github.com/FujiyamaYuta/nuxt-firebase-project
https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest
https://qiita.com/ueokande/items/807a6c9a64c3874a0f83
https://qiita.com/toshihirock/items/e49b66f8685a8510bd76
https://qiita.com/noenture/items/3978f638f2ffb8ff0995