テンプレOGP_2

FlutterでFirebase Authのパスワード変更処理を実装する

今までFlutterではFirebase Authのパスワードリセット処理にSDKが対応しておらず、FirebaseのAPIを叩くみたいなことをしていたのですが、下記のコミットにより追加されました。

今回はその実装方法について書きます。

実装

パスワードリセットに必要な情報として 「登録しているメールアドレス、古いパスワード、新しいパスワードが必要です」

なので自分は下記のような画面を作成しました。

そして、実際のパスワード変更処理は下記です

_changePassword() async {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return Dialog(
            child: Container(
              margin: EdgeInsets.all(20),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  CircularProgressIndicator(),
                  Container(
                    margin: EdgeInsets.all(10),
                    child: const Text("パスワード更新中"),
                  )
                ],
              ),
            ),
          );
        });

    var auth = FirebaseAuth.instance;
    var user = await auth.currentUser();

    auth.reauthenticateWithEmailAndPassword(
        email: _userEmailInputController.text,
        password: _oldPasswordInputController.text).then((_) {

      user.updatePassword(_newPasswordInputController.text).then((success) {
        Navigator.pop(context);
        showDialog(
            context: context,
            barrierDismissible: false,
            builder: (BuildContext context) {
              return AlertDialog(
                title: Text("パスワードを更新しました"),
                actions: <Widget>[
                  FlatButton(
                    child: Text("OK"),
                    onPressed: () {
                      Navigator.pop(context);
                    },
                  )
                ],
              );
            });
      }).catchError((err) {
        Navigator.pop(context);
        _showErrorDialog(err);
      });
    }).catchError((err) {
      Navigator.pop(context);
      _showErrorDialog(err);
    });

  }

_showErrorDialog(err) {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text("エラーが発生しました\n" + err.toString()),
            actions: <Widget>[
              FlatButton(
                child: Text("OK"),
                onPressed: () {
                  Navigator.pop(context);
                },
              )
            ],
          );
        });
  }

この画面全体のコードを載せるとこんな感じ。

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class ChangePassword extends StatefulWidget {
  @override
  _ChangePassword createState() => _ChangePassword();
}

class _ChangePassword extends State<ChangePassword> {
  final _userEmailInputController = new TextEditingController();
  final _oldPasswordInputController = new TextEditingController();
  final _newPasswordInputController = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("パスワードを変更"),
      ),
      body: Center(
        child: Form(
            child: SingleChildScrollView(
          child: Container(
            margin: EdgeInsets.fromLTRB(10, 5, 10, 0),
            child: Column(
              children: <Widget>[
                _formTitle(),
                SizedBox(
                  height: 30,
                ),
                _userEmail(),
                _oldPasswordForm(),
                _newPassword(),
                SizedBox(
                  height: 30,
                ),
                RaisedButton(
                  onPressed: () {
                    _changePassword();
                  },
                  child: Text("変更する"),
                )
              ],
            ),
          ),
        )),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _userEmailInputController.dispose();
    _oldPasswordInputController.dispose();
    _newPasswordInputController.dispose();
  }

  Widget _formTitle() {
    return Text(
      "登録されているメールアドレスと古いパスワードを入力してください",
      style: TextStyle(fontWeight: FontWeight.bold),
    );
  }

  Widget _userEmail() {
    return TextFormField(
      controller: _userEmailInputController,
      autocorrect: false,
      decoration: const InputDecoration(
        border: const UnderlineInputBorder(),
        labelText: '現在のメールアドレス',
      ),
    );
  }

  Widget _oldPasswordForm() {
    return TextFormField(
      controller: _oldPasswordInputController,
      autocorrect: false,
      obscureText: true,
      decoration: const InputDecoration(
        border: const UnderlineInputBorder(),
        labelText: '古いパスワード',
      ),
    );
  }

  Widget _newPassword() {
    return TextFormField(
      controller: _newPasswordInputController,
      autocorrect: false,
      obscureText: true,
      decoration: const InputDecoration(
        border: const UnderlineInputBorder(),
        labelText: '新しいパスワード',
      ),
    );
  }

  _changePassword() async {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return Dialog(
            child: Container(
              margin: EdgeInsets.all(20),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  CircularProgressIndicator(),
                  Container(
                    margin: EdgeInsets.all(10),
                    child: const Text("パスワード更新中"),
                  )
                ],
              ),
            ),
          );
        });

    var auth = FirebaseAuth.instance;
    var user = await auth.currentUser();

    auth.reauthenticateWithEmailAndPassword(
        email: _userEmailInputController.text,
        password: _oldPasswordInputController.text).then((_) {

      user.updatePassword(_newPasswordInputController.text).then((success) {
        Navigator.pop(context);
        showDialog(
            context: context,
            barrierDismissible: false,
            builder: (BuildContext context) {
              return AlertDialog(
                title: Text("パスワードを更新しました"),
                actions: <Widget>[
                  FlatButton(
                    child: Text("OK"),
                    onPressed: () {
                      Navigator.pop(context);
                    },
                  )
                ],
              );
            });
      }).catchError((err) {
        Navigator.pop(context);
        _showErrorDialog(err);
      });
    }).catchError((err) {
      Navigator.pop(context);
      _showErrorDialog(err);
    });

  }

  _showErrorDialog(err) {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text("エラーが発生しました\n" + err.toString()),
            actions: <Widget>[
              FlatButton(
                child: Text("OK"),
                onPressed: () {
                  Navigator.pop(context);
                },
              )
            ],
          );
        });
  }
}

メール認証するのであればこんな実装もやっていきましょう!!


投げ銭はいりません。それより無料でできる拡散をしてください!! 感想をツイートしていただけることが一番嬉しいです!!