Skip to content

Commit

Permalink
Merge pull request #83 from KosukeSaigusa/set_user_mode_host_by_default
Browse files Browse the repository at this point in the history
サインイン直後、ホストドキュメントが存在するなら UserMode を Host にする
  • Loading branch information
kosukesaigusa authored Jul 26, 2023
2 parents 57c67cf + 937362e commit 11569cf
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 16 deletions.
14 changes: 7 additions & 7 deletions packages/mottai_flutter_app/lib/auth/auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,17 @@ final userIdProvider = Provider<String?>((ref) {
});

/// ユーザーがログインしているかどうかを示す bool 値を提供する Provider.
/// [userIdProvider] の変更を watch しているので、ユーザーの認証状態が変更され
/// るたびに、この [Provider] も更新される。
/// [userIdProvider] の変更を watch しているので、ユーザーの認証状態が変更される
/// たびに、この [Provider] も更新される。
final isSignedInProvider = Provider<bool>(
(ref) => ref.watch(userIdProvider) != null,
);

final authServiceProvider = Provider.autoDispose<AuthService>((ref) {
return AuthService(
final authServiceProvider = Provider.autoDispose<AuthService>(
(ref) => AuthService(
workerService: ref.watch(workerServiceProvider),
);
});
),
);

/// [FirebaseAuth] の認証関係の振る舞いを記述するモデル。
class AuthService {
Expand All @@ -55,6 +55,7 @@ class AuthService {
}) : _workerService = workerService;

static final _auth = FirebaseAuth.instance;

final WorkerService _workerService;

// TODO: 開発中のみ使用する。リリース時には消すか、あとで デバッグモード or
Expand Down Expand Up @@ -121,7 +122,6 @@ class AuthService {
}) async {
final user = userCredential.user;
if (user == null) {
// UserCredential
return;
}
final workerExists = await _workerService.workerExists(workerId: user.uid);
Expand Down
52 changes: 43 additions & 9 deletions packages/mottai_flutter_app/lib/auth/ui/auth_controller.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../../../scaffold_messenger_controller.dart';
import '../../exception.dart';
import '../../user/host.dart';
import '../../user/user_mode.dart';
import '../auth.dart';

final authControllerProvider = Provider.autoDispose<AuthController>(
(ref) => AuthController(
authService: ref.watch(authServiceProvider),
hostService: ref.watch(hostServiceProvider),
userModeStateController: ref.watch(userModeStateProvider.notifier),
appScaffoldMessengerController:
ref.watch(appScaffoldMessengerControllerProvider),
),
Expand All @@ -15,36 +21,64 @@ final authControllerProvider = Provider.autoDispose<AuthController>(
class AuthController {
const AuthController({
required AuthService authService,
required HostService hostService,
required StateController<UserMode> userModeStateController,
required AppScaffoldMessengerController appScaffoldMessengerController,
}) : _authService = authService,
_hostService = hostService,
_userModeStateController = userModeStateController,
_appScaffoldMessengerController = appScaffoldMessengerController;

final AuthService _authService;

final HostService _hostService;

final StateController<UserMode> _userModeStateController;

final AppScaffoldMessengerController _appScaffoldMessengerController;

/// 選択した [SignInMethod] でサインインする。
Future<void> signIn(SignInMethod authenticator) async {
switch (authenticator) {
/// サインイン後、該当ユーザーに対応するドキュメントが存在するか確認し、存在
/// する場合は [UserMode] を host にする。
Future<void> signIn(SignInMethod signInMethod) async {
try {
final userCredential = await _signIn(signInMethod);
if (await _hostService.hostExists(
hostId: userCredential.user?.uid ?? '',
)) {
_userModeStateController.update((state) => UserMode.host);
}
} on AppException catch (e) {
_appScaffoldMessengerController.showSnackBarByException(e);
}
}

/// 選択した [SignInMethod] でサインインする。サインインが済んだユーザーの
/// [UserCredential] を返す。
/// 各種の例外が発生した場合には適切なメッセージを入れて [AppException]
/// スローする。呼び元でエラーハンドリングし、スナックバーを表示することを
/// 期待する。
Future<UserCredential> _signIn(SignInMethod signInMethod) async {
switch (signInMethod) {
case SignInMethod.google:
try {
await _authService.signInWithGoogle();
return _authService.signInWithGoogle();
}
// キャンセル時
on PlatformException catch (e) {
if (e.code == 'network_error') {
_appScaffoldMessengerController
.showSnackBar('接続できませんでした。\nネットワーク状況を確認してください。');
throw const AppException(
message: '接続できませんでした。\nネットワーク状況を確認してください。',
);
}
_appScaffoldMessengerController.showSnackBar('キャンセルしました。');
throw const AppException(message: 'キャンセルしました。');
}

case SignInMethod.apple:
// Apple はキャンセルやネットワークエラーの判定ができないので、try-catchしない
await _authService.signInWithApple();
return _authService.signInWithApple();
case SignInMethod.line:
case SignInMethod.email:
throw UnimplementedError();
}
return;
}
}
22 changes: 22 additions & 0 deletions packages/mottai_flutter_app/lib/user/host.dart
Original file line number Diff line number Diff line change
@@ -1 +1,23 @@
import 'package:firebase_common/firebase_common.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../../firestore_repository.dart';

final hostServiceProvider = Provider.autoDispose<HostService>(
(ref) => HostService(
hostRepository: ref.watch(hostRepositoryProvider),
),
);

class HostService {
const HostService({required HostRepository hostRepository})
: _hostRepository = hostRepository;

final HostRepository _hostRepository;

/// 指定した [Host] が存在するかどうかを返す。
Future<bool> hostExists({required String hostId}) async {
final host = await _hostRepository.fetchHost(hostId: hostId);
return host != null;
}
}

0 comments on commit 11569cf

Please sign in to comment.