アプリの基本機能ができました。
ここではユーザーごとに自分が登録したのメモのぺージにアクセスできるようにしていきます。
自分のメモリストは他人に見れないようにします。
目次
ユーザー新規登録ページの作成
まず、ユーザー登録の入力データをデータベースに渡すサービスから作っていきます。
ユーザー新規登録サービスの作成
次のコマンドを実行します。
create()
- create():emailとpasswordを受け取ってAngularFireAuthというFirebase認証機能のcreateUserWithEmailAndPasswordというユーザー作成メソッドを使ってユーザーを新規作成します。
- auth$:ObservableをSubjectによってauthを任意のタイミングで実行します。今回は新規作成ボタンがクリックしされ、createが実行された時にストリームから入力値を受け取れるようにします。
-
set:データベースにuidに紐づいたデータがなければ作成します。
- then():アカウントを作成したらルートパスに戻るようにします。
つまり、createUserWithEmailAndPasswordでユーザー配列が作られます。データベースに同じユーザーIDを持つ配列がなければ 、ユーザー配列を格納します。
update()
- currentUser:今、ログインしているユーザーが格納されているAngularFireAuthのメソッドです。ログインしていなければNULLが返されます。
- updateProfile:メールやパスワードを変えることができるAngularFireAuthのメソッドです。
- db.object:データベースの中から指定の配列を参照するAngularFireDatabaseメソッドです。
this.afAuth.auth.currentUser.uid
:currentUser.uidで取得したユーザーIDを基にユーザーデータがある配列の場所- update(values):上書き保存。valuesは入力した名前です。
つまり、update()が実行されたとき、入力されたユーザー情報を読み込み、そして、IDが一致するユーザーの新しく入力された変更項目をvaluesで上書き保存します。
ユーザークラスを作成
ユーザー情報を格納するユーザークラスを作成します。
ここで、userクラスの型定義をします。
今のところは3つの定義をしておきます。
コメントアウトしている部分はゆくゆく実装する予定です。
コアモジュールに先ほど作成したUserServiceプロバイドさせます。
これで各コンポーネントから読み込めるようになります。
新規登録ページ作成
ユーザー登録用のフォームを作ります。
これでユーザー登録フォーム完成です。
仕組みについてはメイン機能編で作成した新規作成画面と同じです。
気になる方は下のリンクの少し下辺りをどうぞ。
[1ヶ月でAngular] はじめてのアプリ制作!メイン機能編 – まんくつ
新規登録ルーティング設定
ユーザー登録用のサービスとページができたので、ルーティング設定をして、ユーザー登録フォームに遷移できるようにします。
では、app-routingを開き次のコードを追加します。
それとRoutesのエラーパスの上に、
を追加します。
これで、http://localhost:4200/signupにアクセスするとサインアップページが開くようになりました。
メインページからsignupへの導線がないのでヘッダーのloginをsignupに変更して、hrefをrouterLinkに変更します。
これでルーティング設定完了です。
ヘッダーのSignupからユーザーフォームに移動するようになりました。
Firebase認証設定
ユーザーアカウントを登録する方法をfirebaseで設定します。
今回はメールアドレスで登録するようにしていきます。
次のページでその方法は解説しています。
Angular5+Firebaseでチャットアプリを作る④ 新規ユーザー登録編 – まんくつ
解説通りに設定すればユーザー登録ページからユーザー登録ができるようになります。
これでユーザー登録ページは完成です。
ログインページを作成する
サインアップできるようになりました。
次はログインページ、機能を作っていきます。
まずはログイン認証用サービスから作ります。
ログイン認証サービス
ログイン認証用のサービスを作ります。
login()
signInWithEmailAndPassword:AngularFireAuthのサインインのメソッドです。ログインとして使えます。
ログインボタンのイベントでメールアドレスとパスワードを受け取り、該当のユーザーが登録されていればログインできるようにします。
logout()
signOut:AngularFireAuthのサインアウトメソッドです。ログイン中のユーザーをログアウトにします。
ヘッダーのログアウトのクリックイベントにします。
ログインフォームを作る
次のコマンドを実行します。
ログイン情報をログイン認証サービスに渡します。
ヘッダーからログアウトする
ヘッダーに右上からログアウトできるようにしていきます。
ヘッダーコンポーネントで次のコードを定義します。
onAuthStateChangeはログインステータスを返します。ログイン中であればユーザー配列が作られます。そうでなければ、ユーザー配列は空のままです。
配列のあるなしに変化するログインフラグを設定します。
ヘッダーテンプレートのSignupを次のように書き換えます。
ngIfによって、ログインステータスによって表示するテキストを変えられるようにしました。
ログアウトにはログアウトメソッドのクリックイベントを加えました。
また、新規作成アイコンにngIfを加えて、ログイン中のみ表示させるようにしました。
これで、ログイン・ログアウト機能自体はできました。
ルーティング設定
機能が完成したのでちゃんとページ遷移するようにしていきます。
ルートモジュールに次のコードを追加すればOKです。
これでページ遷移できるようになりました。
新規作成するときにヘッダーの更新が追いついていないようです。
原因はよくわかりません・・・
経験不足をアニメーションでごまかす
表示が追いつかないならその間は表示させなければいい!
と原因がわからなかったのでごまかす方法を取りました。
アニメーションをヘッダーのスタイルシートに次のコードを追加しました。
次のように表示を「フワッと」させてごまかしました。
こちらのページを参考にしました。
[CSS3][Sass] 要素を順番にフワッと表示するアニメーションを CSS の animation プロパティで作る | memocarilog
・
・
・
コードを見返したらコードの中にお手本がありました。
適当に検索してできそうなコードをぶっこむのは善くないですね。
次のように変えれば表示がおかしくなりませんでした。
これでログイン・ログアウト機能の基本はとりあえず完成です。
ですが、このアプリはユーザーごとに自分のメインページを表示させたいのでその機能を実装していきます。
ユーザーごとのメインページ
今、データベースは次のようになっています。
- ユーザーはuser.uidをキーにしてuser配列を格納
- メモは指定のmemosに適当なキーを設定してメモ配列を格納
メモ配列をmemos指定ではなく、各ユーザー配列の中に作成するようにしていきます。
階層として次のようなになります。
- uid
- uid
- memos
- memokey1
- id
- isEdit
- main
- sub
- memokey2
- id
- isEdit
- main
- sub
- ・・・
- memokey1
このように、ユーザーの中に作成したメモをそのユーザーの配列内に書き込みます。
ユーザーキーを取得して、その中のmemos配列を読み込むようにすれば自分が登録したメモだけを表示することができるはずです。
では、実装していきます。
ログイン中のユーザーのユーザーキーを取得
ログイン中のユーザーのキーを取得するメソッドはここまでに出てきました。
ヘッダーのSign Inとlogoutの切り替えで使っています。
AngularFirebaseのonAuthStateChangedメソッドです。
これでユーザーのログイン中かどうか判断して、ログイン中であればuidを読み込むようにします。
ログイン中であればuserkeyにユーザーキーが格納されます。
ログインしていなければ、これまでメモを入れていたmemosを格納するようにしました。
では、ユーザーキーを取得できたので、次はこのキーの中を読み書きできるようにしていきます。
ログイン中のユーザーの配列を読み書きする
さて、簡単に取得できたのでここでもサクッと設定していきましょう。
・・・・と思ったのですが、めちゃくちゃ時間がかかりました。
いろいろ試行錯誤の結果、次のコードになりました。
結果的には、先程のコードの下にいままで使っていたスナップショットメソッドをくっつけただけです。
こんな単純なことですが、ngOnInit()の中に二つを別々に入れてみたり、コンストラクタで変化するユーザーキーを無理やり定義しようとしたり、しました。
エラーをたくさん見ましたが、意外と寝て次の日取り掛かったら、すんなりとこの形にたどり着きました。
何が悪かったかというとngOnInit()とコンストラクタの仕組みを理解してなかったからでしょうね。多分。
コンストラクタはクラスを呼び出されたときにだけ定義する。だから、ログイン状況の変化は呼び出さないかぎり分かりません。そのため、メインページは変化を取得しませんが新規作成ページではログイン状態が変わらないため、コンストラクタで定義できるので厄介でした。
ngOnInit()には状況に応じて実行されるコードを置いておく、よくわからんが、別々ではうまく実行してくれないので、やってもらいたいことは一つにまとめる。
ということだと思います。
なんとかユーザー自身のメモのみを表示するようになりました。
ユーザーごとのページにしたはいいものの本当にそうなっているかわかりづらくなってしまいました・・・。
ユーザー名をヘッダーに表示させてみます。
ユーザー名を表示させる
ユーザー関連の機能をユーザーモジュールを作って、そこにまとめたいと思います。
次のコマンドを実行します。
さらに新しくルーティングファイルを作ります。
一つのルーティングファイルにすべて盛り込むとややこしくなるので分けたほうがわかりやすい、場合は分けます。
さらにコンポーネントを作成します。
ここでユーザー名を登録するページを作っていきます。
ユーザーページ作成
ユーザー名を登録するページを作ります。
login.component.cssと同じ
インポートとコンストラクターにも追加します。
update()に入力値をクリックイベントで受け渡します。
これでユーザー名の登録機能を実装しました。
ユーザーページルーティング設定
ユーザー名登録ページに遷移するようにルーティング設定します。
ユーザーズルーティングモジュールにルーティング設定をする前に、アップルーティング設定をしていきます。
routes[]に次のパスを追加します。
これで/usersのパスにはusersルーティングモジュールの設定を読み込むようになります。
続いて、usersルーティングモジュールには次のコードを追加します。
{ path: ‘new’, component: NewUserComponent },
];
そして、@NgModule.importsに次のコードを加えます。
forChild:子要素のルーティングモジュールメソッドです。
適宜、インポートを忘れずに。
さらに、Signup画面でユーザー作成したときに、次のコードを追加してユーザー名登録ページに遷移させます。
ユーザー名を表示
では、ユーザー名の登録ができるようになったので、ユーザ名を表示させていきます。
後は、テンプレートにその値を通せばユーザー名が表示されます。
デザインはあまり気に入っていませんが、凝りだすとハマるのでとりあえずはこれでユーザー名の表示ができるようになりました。
データベースのアクセス権限
ユーザーごとに各々のデータベースを割り当てて、表示自体は自分以外のメモの表示されないようになっています。
しかし、私が知らないだけでおそらくアクセス方法はあるんじゃないかと思います。
そこで、Firebase側でログイン中のユーザーだけが自分のデータベースにアクセスできるようにルールを設定していきます。
次の公式ページに分かりやすくやり方が載っています。
Firebase Realtime Database ルールについて | Firebase Realtime Database | Firebase
設定したらシミュレーターを使って思ったとおりに動作するか確認しましょう。
これでとりあえずはセキュリティも大丈夫になりました。
また、アプリの未ログイン状態のときに表示されるページはサンプルページとしてアカウント関係なく誰でも読み書きできるようにしています。
これで一通り動作するアプリができあがりました。
以降はより使いたくなるようにしていきます。
省略用のshortを実装
名言は長くても60文字以内くらいじゃないのか?
という持論のもとアプリを実装させてきました。
でも、長い言葉も登録したい!という思うこともあるでしょう。
そこで、原文の省略版を登録し、原文ではなく省略版を表示する機能を実装していきます。
名言を自分で変えていいの?と思うかもしれませんが、以外と省略版を作ったほうが面白いです。
言葉を削る上で、いる部分、と要らない部分を分類し、その言葉のどの部分に共感したかというのが明確になります。
では、short実装していきます。
メモクラスの型定義変更
shortのコンストラクタは次のようにしました。
this.short = values.short;
}
else{
this.short = values.main;
}
メモの省略版をパイプを通して表示させることを考えたときに、表示をmainにするかshortにするかの分岐を作るのが面倒だったので、パイプは省略版を表示させるようにしようと思います。
省略版が未設定の場合が多いと思うので、未入力の場合はmainを格納するようにしています。
後はnewコンポーネントのaddMemoでshortを渡すようにすれば実装完了です。
文字の大きさを字数によって変える
文字数に応じてフォントサイズを変えないと短い言葉を登録するとすかすかで寂しくなってしまします。
しかし、よくわからない(T_T)
とりあえずの機能として、ざっくりと実装しました。
if((values.short.length) < 8){
this.size = ‘display-2’}
else if((values.short.length) < 20){
this.size = ‘display-3’}
else if((values.short.length) < 40){
this.size = ‘display-4’}
else{
this.size = ”}
}
文字数ごとにBootstrapの文字数スタイルを当てはめました。
そのまま使うと大きすぎたりしたので、cssでちょうどいいサイズに設定しました。
ただし、ざっくりと設定したので文字数によっては枠からはみ出したりします。
今後の改善点とします。ユーザーが自分で変えれるようにしたいです。
これ以上、拡張するとコードがぐちゃぐちゃになるのでとりあえず機能拡張はここまでにします。
では、残りの細々とした設定をしていきます。
エラーページ作成
次のページと同じ方法で作成しました。
Angular5+Firebaseでチャットアプリを作る④ 新規ユーザー登録編 – まんくつ
アクセス制限
次のページと同じ方法で作成しました。
Angular5+Firebaseでチャットアプリを作る⑤ 完成編 – まんくつ
アプリを公開する
細々とした設定も終わったので、公開の手順に入ります。
いろいろ直すべきところはありますが、明日でタイムリミットの1ヶ月になるのでここまでとします。
次のページと同じ方法でおこないました。
一箇所だけ以前になかったメッセージがありました。
こちらを参考に設定しました。Angular2とFirebase hostingでSPA開発環境を整える – Qiita :
これ以外は下のサイトの通り。
Angular5+Firebaseでチャットアプリを作る⑤ 完成編 – まんくつ
アプリを公開することができました!
メールアドレスの登録が必要ですが今のところは、自動送信して受信できることを確認しないのでデタラメなアドレスでも登録できます(泣)。
なので好きに遊んでみてください。