0%

Flutter 025 - Application Authentication (part9)

前言

Hi, 接著就是來驗證登入狀態,如果已經登入就跳轉到首頁否則就在登入畫面,看完我這句話就知道要使用Bloc了,只要是畫面與功能就要使用到Bloc。以上是一個基本的狀態你還可以檢查有沒有重複登入等…。

完整程式碼

需要具備知識

Authentication:Event

事件分成三個,AppStarted用於開啟APP時觸發的事件,用來檢查有沒有登入,如果沒有就跳轉到登入介面,LoggedIn用於登入成功時觸發把未登入狀態切換成已登入狀態,最後就LoggedOut是登出按鈕觸發時使用,將已登入狀態切換成未登入狀態

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
part of 'authentication_bloc.dart';

abstract class AuthenticationEvent extends Equatable {
const AuthenticationEvent();

@override
List<Object> get props => [];
}

class AppStarted extends AuthenticationEvent {}

class LoggedIn extends AuthenticationEvent {}

class LoggedOut extends AuthenticationEvent {}

Authentication:State

狀態可以分成兩個,未認證與認證,如果認證成功就切換到首頁否則就停留在登入畫面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
part of 'authentication_bloc.dart';

abstract class AuthenticationState extends Equatable {
const AuthenticationState();

@override
List<Object> get props => [];
}

class AuthenticationInitial extends AuthenticationState {}


class Authenticated extends AuthenticationState {
final String displayName;

const Authenticated(this.displayName);

@override
List<Object> get props => [displayName];
}

class Unauthenticated extends AuthenticationState {}

Authentication:Bloc

判斷三個事件所要觸法的功能,寫到這邊時大家應該都對這個架構感覺了吧,是不是覺得越來越美了呢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import 'dart:async';
import 'dart:developer';

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:stunning_tribble/infrastructure/auth/auth_repository.dart';

part 'authentication_event.dart';
part 'authentication_state.dart';

class AuthenticationBloc
extends Bloc<AuthenticationEvent, AuthenticationState> {
final AuthRepository _userRepository;

AuthenticationBloc({
required AuthRepository userRepository,
}) : _userRepository = userRepository,
super(AuthenticationInitial());

@override
Stream<AuthenticationState> mapEventToState(
AuthenticationEvent event,
) async* {
if (event is AppStarted) {
yield* _mapAppStartedToState();
} else if (event is LoggedIn) {
yield* _mapLoggedInToState();
} else if (event is LoggedOut) {
yield* _mapLoggedOutToState();
}
}

Stream<AuthenticationState> _mapAppStartedToState() async* {
final isSignedIn = await _userRepository.isSignedIn();
yield* isSignedIn.fold(
(failure) async* {
log("$failure");
yield Unauthenticated();
},
(isSignedInSuccess) async* {
yield* _mapLoggedInToState();
},
);
}

Stream<AuthenticationState> _mapLoggedInToState() async* {
final user = await _userRepository.getUser();
yield* user.fold(
(failure) async* {
log("$failure");
yield Unauthenticated();
},
(user) async* {
yield Authenticated(user.displayName.toString());
},
);
}

Stream<AuthenticationState> _mapLoggedOutToState() async* {
final signOut = await _userRepository.signOut();
yield* signOut.fold(
(failure) async* {
log("$failure");
yield Unauthenticated();
},
(r) async* {
yield Unauthenticated();
},
);
}
}