完成イメージ
こんな感じ。 pic.twitter.com/CvOFjFq2th
— げん げんと (@gento34165638) November 2, 2019
はじめに
環境は以下の通り
・ionic4
・Nativeとの橋渡しにはcapacitorを使用
・カレンダーについてはionic2-calendarというライブラリーを使用
前回はログインユーザーのデータ取得を実装した。
前回の記事はこちら
概要
実機で確かめるとわかるが、今の所なんと一度アプリを終了させるともう一度ログインする必要があるのだ!!
その5 ユーザー作成と認証から前回の記事で、かなりアプリっぽくはなったが、起動するたびにログインが必要なアプリはあるだろうか?(ファイナンス系はそうだが。。)
毎回ログインさせたく無い時に使うのがネイティブストレージだ。簡単に言えばスマホが持ってる容量にデータを保存させるって事。
やる事は2つ。
①ログインかサインアップをしたら、ネイティブストレージにユーザーデータを保存。
②そして次回以降、もしネイティブストレージにユーザーデータがあれば自動でログインさせる。
プラグインのインストール
公式はこちら
$ ionic cordova plugin add cordova-plugin-nativestorage
$ npm install @ionic-native/native-storage
アカウント作成時にネイティブストレージに保存
まず新規ユーザーはsignup.page
でアカウントを作成する。そこでユーザーデータをストレージに保存する。
import { Router } from '@angular/router';
import { AuthService } from './../auth/auth.service';
import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { ToastController, AlertController } from '@ionic/angular';
import { NativeStorage } from '@ionic-native/native-storage/ngx'; // 追加
@Component({
selector: 'app-signup',
templateUrl: './signup.page.html',
styleUrls: ['./signup.page.scss']
})
export class SignupPage implements OnInit {
signup: {
email: string;
password: string;
name: string;
} = {
email: '',
password: '',
name: ''
};
constructor(
private router: Router,
private afAuth: AngularFireAuth,
private toastCtrl: ToastController,
public authService: AuthService,
private nativeStorage: NativeStorage, // 追加
private alertCtrl: AlertController
) { }
ngOnInit() { }
signUp() {
this.afAuth.auth
.createUserWithEmailAndPassword(this.signup.email, this.signup.password)
.then(created => {
const newUser = created.user;
newUser.updateProfile({
displayName: this.signup.name,
photoURL: ''
})
.then(async () => {
console.log('signup ' + this.signup.name);
const toast = await this.toastCtrl.create({
message: `${created.user.displayName}さんを登録しました`,
duration: 3000
});
// 追加
this.nativeStorage.setItem('email_user', {
uid: newUser.uid,
name: newUser.displayName,
email: newUser.email
});
this.authService.updateUserData(created.user);
this.router.navigateByUrl('/home');
await toast.present();
});
})
.catch(error => {
console.log(error);
const code = error.code;
let message = 'エラーが発生しました。もう一度お試しください。。。';
if (code === 'auth/email-already-in-use') {
message = 'このメールアドレスは既に登録されています。。。';
}
this.showAlert(message);
});
}
goLogin() {
this.router.navigateByUrl('/auth');
}
private showAlert(message: string) {
this.alertCtrl
.create({
header: 'ユーザー登録に失敗',
message: message,
buttons: ['OK']
})
.then(alertEl => alertEl.present());
}
}
ここではemailとパスワードでログインしているので、email_user
という名前で保存。
次はログインの時。
ログイン時にネイティブストレージに保存
仮にスマホを新しくした人がいたとする。当然アカウントがあるのでauth.page
でログインする。
なので、ログイン時もネイティブストレージにユーザーデータを保存したいと思う。
import { AuthService } from './auth.service';
import { Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { ToastController } from '@ionic/angular';
import { AngularFireAuth } from '@angular/fire/auth';
import { LoadingController } from '@ionic/angular';
import { NgForm } from '@angular/forms';
import { NativeStorage } from '@ionic-native/native-storage/ngx'; // 追加
@Component({
selector: 'app-auth',
templateUrl: './auth.page.html',
styleUrls: ['./auth.page.scss']
})
export class AuthPage implements OnInit {
login: {
email: string;
password: string;
} = {
email: '',
password: ''
};
constructor(
private router: Router,
private authService: AuthService,
private toastCtrl: ToastController,
private afAuth: AngularFireAuth,
private loadingCtrl: LoadingController,
private nativeStorage: NativeStorage // 追加
) {}
ngOnInit() {}
async userLogin() {
const loading = await this.loadingCtrl.create({
message: 'ログイン中です'
});
this.presentLoading(loading);
this.authService.login(this.login.email, this.login.password).then(() => {
// 追加
this.afAuth.auth.onAuthStateChanged(user => {
if (user != null) {
this.nativeStorage.setItem('email_user', {
uid: user.uid,
name: user.displayName,
email: user.email
});
}
});
loading.dismiss();
});
}
gotoSignup() {
this.router.navigateByUrl('/signup');
}
gotoReset() {
this.router.navigateByUrl('/reset-password');
}
async presentLoading(loading) {
return await loading.present();
}
}
ログアウト時にストレージからデータを削除
ログアウトしてもストレージにユーザーデータが残っていれば、オートログインされてしまう。
それではログアウトの意味が無いので、ログアウト時にストレージからデータを削除したいと思う。
また、スマホで起動した場合のオートログインをinitializeApp()
で実装。
import { AngularFireAuth } from '@angular/fire/auth';
import { Router } from '@angular/router';
import { Component } from '@angular/core';
import { AuthService, User } from './auth/auth.service';
import { Platform, ToastController, AlertController } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { NativeStorage } from '@ionic-native/native-storage/ngx';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
public currentUser: User;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private router: Router,
private afAuth: AngularFireAuth,
private authService: AuthService,
private toastCtrl: ToastController,
private nativeStorage: NativeStorage,
private alertCtrl: AlertController
) {
this.initializeApp();
this.afAuth.auth.onAuthStateChanged(user => {
if (user != null) {
this.currentUser = user;
} else {
this.router.navigateByUrl('/auth');
}
});
}
initializeApp() {
this.platform.ready().then(() => {
// すでにログインしているユーザーか確認
this.nativeStorage.getItem('email_user').then(
data => {
// もしストレージからデータを取得できたらアクセスさせる
this.router.navigateByUrl('/home');
this.splashScreen.hide();
},
err => {
this.router.navigateByUrl('/auth');
this.splashScreen.hide();
}
);
this.statusBar.styleDefault();
});
}
async logout() {
const alert = await this.alertCtrl.create({
header: 'ログアウトしますか?',
message: '再度ログインするのは面倒ではありませんか?',
buttons: [
{
text: 'キャンセル',
role: 'cancel',
handler: blah => {
console.log('Confirm Cancel: blah');
}
},
{
text: 'ログアウト',
cssClass: 'cancel-button',
handler: async () => {
this.authService.logout().then(async () => {
// 追加
this.nativeStorage.remove('email_user');
const toast = await this.toastCtrl.create({
message: 'ログアウトしました',
duration: 3000
});
await toast.present();
});
this.router.navigateByUrl('/auth');
}
}
]
});
await alert.present();
}
}
最後に
今回で一通りは終わり!アプリとして最低限必要なことはできたと思う。。
各ストアで配信されてます。
興味があれば使ってみてください。