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

【ログアウト】signOutでログイン状態を解除する

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

このページでやること

このページでは、ログアウト機能を作ります。

ログアウトとは、今ログインしている状態を解除して、ログイン画面に戻ることです。

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

FirebaseAuth.instance.signOut()

signOut() は、Firebase Authenticationのログイン状態を解除する命令です。


今日のゴール

チーム一覧画面にログアウトボタンを置いて、押したらログイン画面に戻るようにします。

ログイン済み
↓
チーム一覧画面を見る
↓
ログアウトボタンを押す
↓
Firebase Authenticationのログイン状態が解除される
↓
AuthGateが反応する
↓
LoginPageに戻る

ポイントは、ログアウト後に自分でログイン画面へ移動しなくてもよいことです。

AuthGate がログイン状態の変化を見ているので、自動で画面が切り替わります。


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

単語一言説明
signOut()ログイン状態を解除する命令
FirebaseAuthFirebaseの認証機能をFlutterから使う入口
AuthGateログイン状態で画面を切り替える入口
IconButtonアイコンだけのボタン
AppBar画面上部のバー
async時間がかかる処理を待てる書き方
await処理が終わるまで待つ命令

認証とは、「この人は誰か」を確認する仕組みです。


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

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

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

このページで必要なのは、すでに追加したこのimportです。

import 'package:firebase_auth/firebase_auth.dart';

Step 1:main.dartを開く

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

lib/main.dart

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

code lib/main.dart

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


Step 2:firebase_authのimportを確認する

main.dart の上に、次の1行があるか確認します。

import 'package:firebase_auth/firebase_auth.dart';

この1行がないと、FirebaseAuth が使えません。


Step 3:TeamListPageを探す

main.dart の中で、TeamListPage を探します。

VS Codeなら、検索できます。

command + F

検索する文字はこれです。

class TeamListPage

TeamListPage は、ログイン後に表示するチーム一覧画面です。

まだ仮の画面の場合は、次のような形になっているかもしれません。

class TeamListPage extends StatelessWidget {
  const TeamListPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('トーク'),
      ),
      body: const Center(
        child: Text('チーム一覧画面はあとで作ります'),
      ),
    );
  }
}

Step 4:AppBarにログアウトボタンを追加する

AppBaractions を追加します。

actions とは、AppBarの右側に表示するボタン一覧です。

次のように変更してください。

class TeamListPage extends StatelessWidget {
  const TeamListPage({super.key});

  Future<void> logout() async {
    await FirebaseAuth.instance.signOut();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('トーク'),
        actions: [
          IconButton(
            tooltip: 'ログアウト',
            onPressed: logout,
            icon: const Icon(Icons.logout),
          ),
        ],
      ),
      body: const Center(
        child: Text('チーム一覧画面はあとで作ります'),
      ),
    );
  }
}

これで、画面右上にログアウトアイコンが表示されます。

IconButton は、アイコンだけのボタンです。

Icons.logout は、ログアウトを表すアイコンです。


Step 5:logout()の中身を見る

追加したログアウト処理はここです。

Future<void> logout() async {
  await FirebaseAuth.instance.signOut();
}

短く言うと、こうです。

Firebase Authenticationに対して
↓
ログアウトしてください
↓
とお願いしている

Future<void> は、時間がかかる処理を表します。

async は、時間がかかる処理を待てるようにする書き方です。

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


Step 6:なぜ画面移動を書かないのか

ログアウト処理には、次のような画面移動を書いていません。

Navigator.of(context).push(...)

理由は、AuthGate があるからです。

AuthGate は、ログイン状態を見て画面を切り替える入口です。

signOut() を実行
↓
ログイン状態が解除される
↓
AuthGateが変化に気づく
↓
LoginPageを表示する

つまり、ログアウト後の画面切り替えは、AuthGate に任せます。

この方がコードがシンプルになります。


Step 7:保存する

main.dart を保存します。

Macの場合:

command + S

Windowsの場合:

Ctrl + S

Step 8:実行する

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

flutter run

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

r

画面がうまく切り替わらない場合は、R を押してホットリスタートしてください。

R

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

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


Step 9:ログアウトを試す

すでにログインしている場合は、チーム一覧画面が表示されます。

右上のログアウトアイコンを押してください。

右上のログアウトアイコン
↓
押す
↓
ログイン画面に戻る

ログイン画面に戻れば成功です。


Step 10:ログインしていない場合

ログインしていない状態では、AuthGate によってログイン画面が表示されます。

その場合は、先に新規登録またはログインをしてください。

ログイン画面
↓
メールアドレスとパスワードを入力
↓
ログイン
↓
チーム一覧画面
↓
ログアウト確認

1か所だけ変更してみる

ログアウトアイコンの説明文を変えてみます。

この部分を探してください。

tooltip: 'ログアウト',

次のように変えます。

tooltip: 'サインアウト',

保存して、ホットリロードします。

r

アイコンを長押し、またはマウスを重ねたときの説明が変わればOKです。

確認できたら、好きな表現に戻して大丈夫です。


確認ダイアログを出したい場合

いきなりログアウトするのが不安な場合は、確認画面を出すこともできます。

ダイアログとは、画面の上に出る確認用の小さな画面です。

必要な場合は、logout() を次のように変更します。

Future<void> logout(BuildContext context) async {
  final shouldLogout = await showDialog<bool>(
    context: context,
    builder: (context) {
      return AlertDialog(
        title: const Text('ログアウトしますか?'),
        content: const Text('現在のログイン状態を解除します。'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(false),
            child: const Text('キャンセル'),
          ),
          FilledButton(
            onPressed: () => Navigator.of(context).pop(true),
            child: const Text('ログアウト'),
          ),
        ],
      );
    },
  );

  if (shouldLogout == true) {
    await FirebaseAuth.instance.signOut();
  }
}

その場合、ボタン側はこうします。

IconButton(
  tooltip: 'ログアウト',
  onPressed: () => logout(context),
  icon: const Icon(Icons.logout),
),

最初は確認なしの短い版でOKです。


よくあるエラーと直し方

エラー原因直し方
FirebaseAuth isn't definedimportがないfirebase_auth.dart をimportする
Icons.logout が見つからないMaterialのimportがないmaterial.dart をimportする
logout が見つからない関数を書いた場所が違うTeamListPage の中に書く
押しても戻らないAuthGateを通っていないhome: const AuthGate() を確認
画面が変わらない保存していないcommand + S
ホットリロードで反映されない状態が残っているR または再起動

FirebaseAuth isn't defined** が出たとき**

main.dart の上に、次の1行があるか確認します。

import 'package:firebase_auth/firebase_auth.dart';

なければ追加してください。

保存して、もう一度実行します。

flutter run

押してもログイン画面に戻らないとき

まず、MaterialApphome が次のようになっているか確認します。

home: const AuthGate(),

これが別の画面になっていると、ログイン状態の変化で画面が切り替わりません。

次に、AuthGate が次のようにログイン状態を見ているか確認します。

stream: FirebaseAuth.instance.authStateChanges(),

この2つがあれば、signOut() 後にログイン画面へ戻ります。


最短作業まとめ

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

1. importを確認

import 'package:firebase_auth/firebase_auth.dart';

2. TeamListPageにlogout()を追加

Future<void> logout() async {
  await FirebaseAuth.instance.signOut();
}

3. AppBarにログアウトボタンを追加

appBar: AppBar(
  title: const Text('トーク'),
  actions: [
    IconButton(
      tooltip: 'ログアウト',
      onPressed: logout,
      icon: const Icon(Icons.logout),
    ),
  ],
),

4. 保存して実行

flutter run

チェックリスト

□ main.dartを開いた
□ firebase_authをimportした
□ TeamListPageを探した
□ logout()を書いた
□ FirebaseAuth.instance.signOut()を書いた
□ AppBarにactionsを追加した
□ IconButtonを追加した
□ 保存した
□ flutter runで起動した
□ ログアウトボタンを押した
□ ログイン画面に戻った

ミニ確認問題

Q1. signOut() は何をする命令ですか?

回答

Firebase Authenticationのログイン状態を解除する命令です。


Q2. ログアウト後に、なぜ自分でログイン画面へ移動しなくてもよいのですか?

回答

AuthGate がログイン状態を監視しているからです。

signOut() でログイン状態が解除されると、AuthGate が自動で LoginPage を表示します。


Q3. AppBaractions は何をする場所ですか?

回答

AppBarの右側に表示するボタンを置く場所です。

今回なら、ログアウトボタンを置きます。


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

回答

必要ありません。

このページでは、signOut() を使ったログアウト処理を作るだけです。


このページのまとめ

  • このページでは、ログアウト機能を作った。
  • ログアウトには FirebaseAuth.instance.signOut() を使う。
  • ログアウトボタンは、チーム一覧画面のAppBar右側に置く。
  • IconButton を使うと、アイコンだけのボタンを作れる。
  • ログアウト後は、AuthGate が自動でログイン画面に切り替える。
  • そのため、ログアウト処理の中で画面移動を書く必要はない。
  • このページではnpmや環境変数は不要。

次のページでやること

次のページでは、Firestoreのデータ構造を整理します。

usersteamsmemberstasks がどのようにつながるのかを確認して、チーム作成に進む準備をします。

教材トップへ戻る