Flutter

[Android]Firebase-Logout 구현 + 로그인한 사람 표시

모리선생 2023. 4. 26. 23:40
728x90

목표

Logout 기능을 구현하고 로그인한 사람의 정보를 화면에 표시를 한다.


 

이전 시간에 배웠던 Login 기능을 구현한 코드에 추가하여 작성을 진행해보자.

https://riris01.tistory.com/35

 

[Android] Firebase-Login 구현하기

목표 Firebase를 사용하여 Login을 구현하여 본다. Login에 필요한 화면 구성과 더불어서 필요한 위젯이 무엇인지 확인하고 코드 본문에 기입할 수 있는 방법을 확인한다. 저번 포스팅에서 Firebase와

riris01.tistory.com

 

이번 코드는 여기서 다운이 가능하다.

https://github.com/riris01/firebase_signin_name_signup

 

계속해서 코드 작성 시작!

 

1. login_page.dart

_login() 메소드에서 Get.offAll(() => const MarketPage());를 추가함으로써 페이지 이동할 시 중간 Stack들을 무시하고 바로 MarketPage()로 이동할 수 있도록 코드를 제작하였다. 

(...)

_login() async {
    if (_formKey.currentState!.validate()) {
      FocusScope.of(context).requestFocus(FocusNode());

      try {
        await FirebaseAuth.instance.signInWithEmailAndPassword(
          email: _emailController.text,
          password: _passwordController.text,
        );

        // navigate to a new screen and remove all the previous screens
        Get.offAll(() => const MarketPage());

        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Logged in')),
        );
      } on FirebaseAuthException catch (e) {
        String message = 'Hello';

        if (e.code == 'user-not-found') {
          message = 'The user does not exist.';
        } else if (e.code == 'wrong-password') {
          message = 'Check your password.';
        } else if (e.code == 'invalid-email') {
          message = 'Check your email.';
        }

        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text(message), backgroundColor: Colors.black),
        );
      }
    }
  }
  
  (...)

 

2. my_home_page.dart

login_page.dart에서 추가했던 것처럼 일정 시간을 대기하고 난후 (millisecons: 100) Get.off로 MarketPage()로 이동할 수 있도록 추가를 하였으며, 만약 currentUser == null인 존재하지 않은 상황 (=로그인을 하지 않은 상황이라면) Get.off()를 통해 LoginPage()로 이동할 수 있도록 코드를 작성하였다.

(...)

_auth() {
    Future.delayed(const Duration(milliseconds: 100), () {
      if (FirebaseAuth.instance.currentUser == null) {
        Get.off(() => const LoginPage());
      } else {
        Get.off(() => const MarketPage());
      }
    });
  }
  
 (...)

 

3. market_page.dart

로그아웃 기능 구현 및 메시지 구현 (에러발생시 로그인 실패 메시지도 첨부)

즉, _isLoggedIn이 false가 되는 경우 SnackBar를 통해 로그아웃했다는 표시가 발생을 하며, 이와 동시에 navigator.pushAndRemoveUntil 메서드를 사용하여 기존 페이지였던 LoginPage()로 이동할 수 있도록 하였다.

(...)

Future<void> _logout() async {
    try {
      await FirebaseAuth.instance.signOut();
      setState(() {
        _isLoggedIn = false;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('You have signed out')),
      );
      Navigator.pushAndRemoveUntil(
          context,
          MaterialPageRoute(builder: (BuildContext context) => LoginPage()),
          (Route<dynamic> route) => false);
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
        content: Text('Sign out failed'),
      ));
    }
  }
}
  
 (...)

 

근데, 이게 로그인을 했는지 안했는지 구분이 안간다. 그러한 경우에는 앱 상단에 현재 로그인한 사람의 ID 혹은 이메일들을 불러와서 누가 현재 앱에 로그인을 한 상태로 사용을 하고 있는지 확인하도록 할 수 있다. 이때, 사용한 방법은 _isLoggedIn이 true일때, currentUser의 email을 불러오고 toString()으로 처리해 표시하도록 처리하였다. 

 

그리고 _logout 메서드를 IconButton()에 삽입하여, 로그아웃이 진행될 수 있도록 하였다.

 

아 참고로 body()에는 무언가 비어있는것이 아쉬워서 노란색 색깔별로 박스 몇개를 만들어두어보았다.

(...)

@override
  void initState() {
    super.initState();
    _isLoggedIn = FirebaseAuth.instance.currentUser != null;
  }

  @override
  Widget build(BuildContext context) {
    final List<String> entries = <String>['a', 'b', 'c', 'd', 'e'];
    final List<int> colorCodes = <int>[600, 500, 400, 300, 200];

    return Scaffold(
      appBar: AppBar(
        title: Text('Potato Market'),
        actions: [
          Padding(
            padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
            child: Row(
              children: [
                if (_isLoggedIn)
                  Text(FirebaseAuth.instance.currentUser!.email.toString())
                else
                  Text('Please login'), // 조건문 추가
                IconButton(
                    onPressed: () => _logout(),
                    icon: Icon(Icons.exit_to_app_sharp)),
              ],
            ),
          ),
        ],
      ),
      body: ListView.separated(
        padding: const EdgeInsets.all(8),
        itemCount: entries.length,
        itemBuilder: (BuildContext context, int index) {
          return Container(
            height: 100,
            width: 400,
            color: Colors.amber[colorCodes[index]],
            child: Center(
              child: Text('In order ${entries[index]}'),
            ),
          );
        },
        separatorBuilder: (BuildContext context, index) => const Divider(),
      ),
    );
  }

(...)

 

전체코드 (market_page.dart)

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_login_practice/login_page.dart';
import 'package:flutter_login_practice/my_home_page.dart';

class MarketPage extends StatefulWidget {
  const MarketPage({super.key});

  @override
  State<MarketPage> createState() => _MarketPageState();
}

class _MarketPageState extends State<MarketPage> {
  bool _isLoggedIn = false; //state variable 추가

  @override
  void initState() {
    super.initState();
    _isLoggedIn = FirebaseAuth.instance.currentUser != null;
  }

  @override
  Widget build(BuildContext context) {
    final List<String> entries = <String>['a', 'b', 'c', 'd', 'e'];
    final List<int> colorCodes = <int>[600, 500, 400, 300, 200];

    return Scaffold(
      appBar: AppBar(
        title: Text('Potato Market'),
        actions: [
          Padding(
            padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
            child: Row(
              children: [
                if (_isLoggedIn)
                  Text(FirebaseAuth.instance.currentUser!.email.toString())
                else
                  Text('Please login'), // 조건문 추가
                IconButton(
                    onPressed: () => _logout(),
                    icon: Icon(Icons.exit_to_app_sharp)),
              ],
            ),
          ),
        ],
      ),
      body: ListView.separated(
        padding: const EdgeInsets.all(8),
        itemCount: entries.length,
        itemBuilder: (BuildContext context, int index) {
          return Container(
            height: 100,
            width: 400,
            color: Colors.amber[colorCodes[index]],
            child: Center(
              child: Text('In order ${entries[index]}'),
            ),
          );
        },
        separatorBuilder: (BuildContext context, index) => const Divider(),
      ),
    );
  }

  Future<void> _logout() async {
    try {
      await FirebaseAuth.instance.signOut();
      setState(() {
        _isLoggedIn = false;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('You have signed out')),
      );
      Navigator.pushAndRemoveUntil(
          context,
          MaterialPageRoute(builder: (BuildContext context) => LoginPage()),
          (Route<dynamic> route) => false);
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
        content: Text('Sign out failed'),
      ));
    }
  }
}

 

구동화면

728x90

'Flutter' 카테고리의 다른 글

[Android]Firebase-todo  (0) 2023.04.29
[Android]Firebase-Signup  (0) 2023.04.27
[Android] Firebase-Login 구현하기  (0) 2023.04.25
[Android] Firebase - Flutter 연결하기  (0) 2023.04.25
[Package] flutter_animate  (0) 2023.04.23