0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ionic + Firebaseで記録するカレンダーアプリを作る その9 オートログイン ストレージにユーザーデータを保存

Last updated at Posted at 2019-11-20

完成イメージ

はじめに

環境は以下の通り
・ionic4
・Nativeとの橋渡しにはcapacitorを使用
・カレンダーについてはionic2-calendarというライブラリーを使用

前回はログインユーザーのデータ取得を実装した。
:point_right:前回の記事はこちら

概要

実機で確かめるとわかるが、今の所なんと一度アプリを終了させるともう一度ログインする必要があるのだ!!

その5 ユーザー作成と認証から前回の記事で、かなりアプリっぽくはなったが、起動するたびにログインが必要なアプリはあるだろうか?(ファイナンス系はそうだが。。)

毎回ログインさせたく無い時に使うのがネイティブストレージだ。簡単に言えばスマホが持ってる容量にデータを保存させるって事。

やる事は2つ。
①ログインかサインアップをしたら、ネイティブストレージにユーザーデータを保存。
②そして次回以降、もしネイティブストレージにユーザーデータがあれば自動でログインさせる。

プラグインのインストール

公式はこちら

$ ionic cordova plugin add cordova-plugin-nativestorage
$ npm install @ionic-native/native-storage

アカウント作成時にネイティブストレージに保存

まず新規ユーザーはsignup.pageでアカウントを作成する。そこでユーザーデータをストレージに保存する。

signup.page.ts
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でログインする。
なので、ログイン時もネイティブストレージにユーザーデータを保存したいと思う。

auth.page.ts
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();
  }
}

最後に

今回で一通りは終わり!アプリとして最低限必要なことはできたと思う。。

各ストアで配信されてます。
興味があれば使ってみてください。:relieved:

Apple Store

Google Play

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?