Flutterアプリケーション開発概論

【ユーザー作成】createUserWithEmailAndPasswordでアカウントを作成する

15LINE風チームタスク管理アプリを作りながら、ログイン・データベース・権限管理を学ぶ
FlutteriOSAndroidMacOSWindows基礎から学ぶ開発アプリ開発

このページでやること

このページでは、新規登録ボタンを押したときに、Firebase Authenticationへユーザーを作成します。

Firebase Authenticationとは、Firebaseのログイン・新規登録を担当する機能です。

今回使う命令はこれです。

FirebaseAuth.instance.createUserWithEmailAndPassword()

createUserWithEmailAndPassword は、メールアドレスとパスワードで新しいアカウントを作る命令です。


今日のゴール

前のページでは、新規登録画面の見た目だけを作りました。

今回は、仮の register() を本物の登録処理に変更します。

完成すると、次の流れで動きます。

名前を入力する
↓
所属を入力する
↓
メールアドレスを入力する
↓
パスワードを入力する
↓
新規登録ボタンを押す
↓
Firebase Authenticationにアカウントを作成する
↓
成功したらログイン済みになる

Firebase Authenticationでアカウント作成に成功すると、そのままログイン状態になります。


このページで出てくる単語

単語一言説明
createUserWithEmailAndPasswordメールとパスワードで新しいユーザーを作る命令
UserCredentialFirebaseから返ってくる登録結果
uidFirebaseがユーザーごとに発行するID
tryエラーが起きるかもしれない処理を書く場所
catchエラーが起きたときの処理を書く場所
finally成功しても失敗しても最後に動く場所
isLoading登録中かどうかを表す変数
errorTextエラー文を入れる変数

uid は、ユーザーを区別するためのIDです。

IDとは、データを見分けるための名前や番号のことです。


npmや環境変数はこのページで必要?

このページでは、npmは使いません。

環境変数も設定しません。

必要なのは、すでに追加した firebase_auth です。

main.dart の上に、次のimportがあるか確認してください。

import 'package:firebase_auth/firebase_auth.dart';

import とは、別の機能をこのファイルで使えるように読み込むことです。


Step 1:Firebase Consoleでメールログインを有効にする

コードを書く前に、Firebase Consoleでメールログインを有効にします。

これをしないと、メールアドレスとパスワードで登録できません。

次の流れで進めます。

Firebase Consoleを開く
↓
Authenticationを開く
↓
Sign-in methodを開く
↓
メール / パスワードを有効にする
↓
保存する

Firebase Consoleはこちらです。

https://console.firebase.google.com/

画面では、次の項目を探します。

Authentication
↓
Sign-in method
↓
Email/Password

Email/Password を有効にしてください。


Step 2:main.dartを開く

Flutterプロジェクトの中で、次のファイルを開きます。

lib/main.dart

VS Codeを使っている場合は、ターミナルで次を実行してもOKです。

code lib/main.dart

code が使えない場合は、VS Codeの左側から lib/main.dart を開いてください。


Step 3:今のregister()を探す

前のページで作った RegisterPage の中に、次のような register() があります。

Future<void> register() async {
  setState(() {
    errorText = null;
  });

  final displayName = displayNameController.text.trim();
  final department = departmentController.text.trim();
  final email = emailController.text.trim();
  final password = passwordController.text;

  if (displayName.isEmpty ||
      department.isEmpty ||
      email.isEmpty ||
      password.isEmpty) {
    setState(() {
      errorText = 'すべての項目を入力してください。';
    });
    return;
  }

  setState(() {
    errorText = '次のページでFirebase登録処理を追加します。';
  });
}

この仮コードを、本物の登録処理に差し替えます。


Step 4:register()を差し替える

先ほどの register() を、次のコードに置き換えてください。

Future<void> register() async {
  setState(() {
    isLoading = true;
    errorText = null;
  });

  final displayName = displayNameController.text.trim();
  final department = departmentController.text.trim();
  final email = emailController.text.trim();
  final password = passwordController.text;

  if (displayName.isEmpty ||
      department.isEmpty ||
      email.isEmpty ||
      password.isEmpty) {
    setState(() {
      isLoading = false;
      errorText = 'すべての項目を入力してください。';
    });
    return;
  }

  try {
    final credential =
        await FirebaseAuth.instance.createUserWithEmailAndPassword(
      email: email,
      password: password,
    );

    final user = credential.user;

    if (user == null) {
      setState(() {
        errorText = 'ユーザー作成に失敗しました。';
      });
      return;
    }

    if (mounted) {
      Navigator.of(context).pop();
    }
  } on FirebaseAuthException catch (e) {
    setState(() {
      errorText = e.message ?? '新規登録に失敗しました。';
    });
  } catch (_) {
    setState(() {
      errorText = '新規登録に失敗しました。';
    });
  } finally {
    if (mounted) {
      setState(() {
        isLoading = false;
      });
    }
  }
}

これで、新規登録ボタンを押したときに、Firebase Authenticationへアカウントを作成できます。


Step 5:コードの流れを短く理解する

全部を覚える必要はありません。

まずは流れだけ分かればOKです。

入力された文字を取り出す
↓
空欄がないか確認する
↓
Firebaseにアカウント作成を依頼する
↓
成功したらログイン済みになる
↓
失敗したらエラーを表示する

新規登録は、だいたいこの流れで作ります。


Step 6:入力された文字を取り出す

この部分を見ます。

final displayName = displayNameController.text.trim();
final department = departmentController.text.trim();
final email = emailController.text.trim();
final password = passwordController.text;

TextEditingController は、入力欄の文字を取り出すための道具です。

trim() は、前後の空白を消す処理です。

たとえば、メールアドレスの後ろに空白が入ってしまっても、ミスを減らせます。

"test@example.com "
↓
"test@example.com"

Step 7:空欄チェックをする

この部分です。

if (displayName.isEmpty ||
    department.isEmpty ||
    email.isEmpty ||
    password.isEmpty) {
  setState(() {
    isLoading = false;
    errorText = 'すべての項目を入力してください。';
  });
  return;
}

isEmpty は、文字が空かどうかを調べるものです。

|| は、「または」という意味です。

つまり、ここではこう見ています。

名前が空
または
所属が空
または
メールが空
または
パスワードが空
↓
エラーを表示する

return は、ここで処理を止めるという意味です。


Step 8:Firebase Authenticationにユーザーを作る

一番大事なのは、この部分です。

final credential =
    await FirebaseAuth.instance.createUserWithEmailAndPassword(
  email: email,
  password: password,
);

ここで、Firebase Authenticationへ新しいユーザー作成を依頼しています。

await は、処理が終わるまで待つ命令です。

ユーザー作成は通信処理なので、少し時間がかかることがあります。

通信処理とは、インターネット経由でFirebaseとやり取りする処理のことです。


Step 9:UserCredentialとは何か

この部分を見ます。

final credential =
    await FirebaseAuth.instance.createUserWithEmailAndPassword(
  email: email,
  password: password,
);

credential には、登録結果が入ります。

UserCredential とは、Firebase Authenticationから返ってくるログイン・登録結果です。

この中に、作成されたユーザー情報が入っています。

次のように取り出します。

final user = credential.user;

user の中には、Firebase上のユーザー情報が入ります。


Step 10:uidを確認する

Firebaseで作成されたユーザーには、uid があります。

final user = credential.user;

この user から、次のように uid を取り出せます。

final uid = user.uid;

uid は、ユーザーごとに発行されるIDです。

今回のページでは、まだ uid をFirestoreに保存しません。

次のページで、users/{uid} にプロフィールを保存します。

Firebase Authenticationでユーザー作成
↓
uidを取得
↓
次のページでFirestoreにプロフィール保存

Step 11:成功したらなぜログイン済みになるのか

createUserWithEmailAndPassword でユーザー作成に成功すると、そのユーザーは自動でログイン状態になります。

つまり、次のように動きます。

新規登録成功
↓
Firebase Authenticationのログイン状態が変わる
↓
AuthGateが変化に気づく
↓
TeamListPageに切り替わる

AuthGate は、ログイン済み・未ログインで画面を切り替える入口です。

そのため、登録後に手動でチーム一覧へ移動しなくても、ログイン状態に合わせて画面が変わります。


Step 12:エラーが出たとき

この部分です。

} on FirebaseAuthException catch (e) {
  setState(() {
    errorText = e.message ?? '新規登録に失敗しました。';
  });
}

FirebaseAuthException は、Firebase Authenticationで起きたエラーです。

たとえば、次のような場合に出ます。

エラーになる例内容
メール形式が間違っているtestexample.com のように @ がない
パスワードが短いFirebaseでは短すぎるパスワードは使えない
すでに登録済み同じメールアドレスがすでに使われている
メールログインが無効Firebase ConsoleでEmail/Passwordが有効になっていない

失敗したら、errorText にエラー文を入れます。

errorText に文字が入ると、画面に ErrorBox が表示されます。


Step 13:登録中の表示

この部分で、登録中かどうかを管理しています。

setState(() {
  isLoading = true;
  errorText = null;
});

登録処理が始まったら、isLoadingtrue にします。

そして最後に、false に戻します。

finally {
  if (mounted) {
    setState(() {
      isLoading = false;
    });
  }
}

finally は、成功しても失敗しても最後に動く場所です。

mounted は、この画面がまだ表示中かどうかを確認するものです。

画面が消えているのに setState するとエラーになるため、念のため確認します。


Step 14:新規登録ボタンとつなげる

ボタン部分が、次のようになっているか確認します。

FilledButton(
  onPressed: isLoading ? null : register,
  child: Text(isLoading ? '登録中...' : '新規登録'),
),

onPressed は、ボタンを押したときの処理です。

isLoadingtrue のときは、ボタンを押せないようにします。

登録中
↓
ボタンを押せない

登録中ではない
↓
ボタンを押すとregister()が動く

Step 15:保存する

main.dart を保存します。

Macの場合:

command + S

Windowsの場合:

Ctrl + S

Step 16:実行する

ターミナルで実行します。

flutter run

すでに起動している場合は、ターミナルで r を押します。

r

画面構成を大きく変えた場合は、R を押すか、アプリを再起動してください。

r はホットリロードです。

R はホットリスタートです。

ホットリスタートとは、アプリの状態を一度リセットして起動し直す機能です。


Step 17:新規登録を試す

ログイン画面から、次を押します。

新規登録はこちら

新規登録画面で、次のように入力します。

名前:山田太郎
所属:開発チーム
メールアドレス:test@example.com
パスワード:password123

メールアドレスは、実際に使える形にしてください。

学習用なら、自分のテスト用メールでOKです。

入力できたら、次を押します。

新規登録

成功すると、Firebase Authenticationにユーザーが作成されます。


Step 18:Firebase Consoleで確認する

Firebase Consoleを開きます。

https://console.firebase.google.com/

次の画面へ進みます。

Authentication
↓
Users

登録したメールアドレスが表示されていれば成功です。

test@example.com

ここに表示されていれば、Firebase Authenticationへのアカウント作成はできています。


Step 19:画面がどう変わるか確認する

登録に成功すると、ログイン状態になります。

そのため、AuthGate が反応して、チーム一覧画面へ切り替わります。

新規登録成功
↓
ログイン済みになる
↓
AuthGateがTeamListPageを表示する

もしまだ TeamListPage が仮画面なら、次のような表示でもOKです。

チーム一覧画面はあとで作ります

このページでは、Firebase Authenticationにユーザーが作られることがゴールです。


よくあるエラーと直し方

エラー原因直し方
FirebaseAuth isn't definedimportがないfirebase_auth.dart をimportする
createUserWithEmailAndPassword isn't defined書く場所や呼び出し方が違うFirebaseAuth.instance から呼ぶ
setState isn't definedState クラスの外に書いている_RegisterPageState の中に書く
email-already-in-useそのメールは登録済み別のメールを使う
weak-passwordパスワードが短い6文字以上にする
invalid-emailメール形式が正しくない@ を含むメールにする
operation-not-allowedメールログインが無効Firebase ConsoleでEmail/Passwordを有効にする
画面が変わらない保存していないcommand + S
登録後に切り替わらないAuthGateがないhome: const AuthGate() を確認

operation-not-allowed** が出たとき**

このエラーは、Firebase Consoleでメールログインが有効になっていないときに出ます。

次の順番で確認してください。

Firebase Console
↓
Authentication
↓
Sign-in method
↓
Email/Password
↓
有効にする
↓
保存

保存したあと、もう一度新規登録を試してください。


email-already-in-use** が出たとき**

これは、そのメールアドレスがすでに登録されているという意味です。

学習中なら、別のメールアドレスで試してください。

例:

test1@example.com
test2@example.com
test3@example.com

または、Firebase ConsoleのAuthenticationからテストユーザーを削除して、もう一度試すこともできます。


weak-password** が出たとき**

これは、パスワードが弱すぎるという意味です。

まずは、6文字以上のパスワードにしてください。

例:

password123
test1234
sample999

本番アプリでは、もっと強いパスワードを使う必要があります。

本番アプリとは、実際のユーザーに公開するアプリのことです。


invalid-email** が出たとき**

これは、メールアドレスの形式が正しくないという意味です。

次のように、@ を含む形式にしてください。

test@example.com

これはNGです。

testexample.com

最短作業まとめ

読むのが大変な人は、ここだけ見てください。

1. Firebase ConsoleでEmail/Passwordを有効化

Firebase Console
↓
Authentication
↓
Sign-in method
↓
Email/Passwordを有効化

2. importを確認

import 'package:firebase_auth/firebase_auth.dart';

3. register()を差し替える

Future<void> register() async {
  setState(() {
    isLoading = true;
    errorText = null;
  });

  final displayName = displayNameController.text.trim();
  final department = departmentController.text.trim();
  final email = emailController.text.trim();
  final password = passwordController.text;

  if (displayName.isEmpty ||
      department.isEmpty ||
      email.isEmpty ||
      password.isEmpty) {
    setState(() {
      isLoading = false;
      errorText = 'すべての項目を入力してください。';
    });
    return;
  }

  try {
    final credential =
        await FirebaseAuth.instance.createUserWithEmailAndPassword(
      email: email,
      password: password,
    );

    final user = credential.user;

    if (user == null) {
      setState(() {
        errorText = 'ユーザー作成に失敗しました。';
      });
      return;
    }

    if (mounted) {
      Navigator.of(context).pop();
    }
  } on FirebaseAuthException catch (e) {
    setState(() {
      errorText = e.message ?? '新規登録に失敗しました。';
    });
  } catch (_) {
    setState(() {
      errorText = '新規登録に失敗しました。';
    });
  } finally {
    if (mounted) {
      setState(() {
        isLoading = false;
      });
    }
  }
}

4. 保存して実行

flutter run

チェックリスト

□ Firebase ConsoleでEmail/Passwordを有効にした
□ main.dartを開いた
□ firebase_authをimportした
□ register()を差し替えた
□ createUserWithEmailAndPasswordを書いた
□ 空欄チェックを書いた
□ エラー表示を書いた
□ 登録中はボタンを押せないようにした
□ 保存した
□ flutter runで起動した
□ 新規登録を試した
□ Firebase ConsoleのAuthenticationでユーザーを確認した

ミニ確認問題

Q1. createUserWithEmailAndPassword は何をする命令ですか?

回答

メールアドレスとパスワードを使って、Firebase Authenticationに新しいユーザーを作成する命令です。


Q2. 新規登録に成功すると、ログイン状態になりますか?

回答

はい。

Firebase Authenticationでは、createUserWithEmailAndPassword に成功すると、そのユーザーはログイン状態になります。


Q3. uid は何に使いますか?

回答

ユーザーを区別するために使います。

次のページでは、この uid を使って、Firestoreの users/{uid} にプロフィールを保存します。


Q4. このページでnpmや環境変数は必要ですか?

回答

必要ありません。

このページでは、Firebase Authenticationへユーザーを作る処理を追加するだけです。


このページのまとめ

  • このページでは、Firebase Authenticationへ新しいユーザーを作成した。
  • createUserWithEmailAndPassword を使うと、メールアドレスとパスワードでアカウントを作れる。
  • 登録前に、名前・所属・メール・パスワードの空欄チェックをする。
  • 登録中は isLoadingtrue にして、ボタンを押せないようにする。
  • 登録に失敗したら、errorText にエラー文を入れて画面に表示する。
  • 登録に成功すると、そのユーザーはログイン状態になる。
  • 登録したユーザーはFirebase ConsoleのAuthenticationで確認できる。
  • このページではnpmや環境変数は不要。

次のページでやること

次のページでは、作成したユーザーのプロフィールをFirestoreに保存します。

名前、所属、メールアドレス、uidを users/{uid} に保存して、アプリ内で使えるユーザー情報を作ります。

教材トップへ戻る