해당 강의를 학습하면서 정리한 글입니다. (강력추천)
https://www.udemy.com/course/flutter-provider-essential-korean/
! 사용import 'package:cloud_firestore/cloud_firestore.dart';
import '../constants/db_constants.dart';
import '../models/custom_error.dart';
import '../models/user_model.dart';
class ProfileRepository {
final FirebaseFirestore firebaseFirestore;
ProfileRepository({
required this.firebaseFirestore,
});
Future<User> getProfile({required String uid}) async {
try {
final DocumentSnapshot userDoc = await usersRef.doc(uid).get();
if (userDoc.exists) {
//firestore에서 읽어오는 document가 존재하지 않을 수도 있음.
final User currentUser = User.fromDoc(userDoc);
return currentUser;
}
throw 'User not found';
} on FirebaseException catch (e) {
throw CustomError(
code: e.code,
message: e.message!,
plugin: e.plugin,
);
} catch (e) {
throw CustomError(
code: 'Exception',
message: e.toString(),
plugin: 'flutter_error/server_error',
);
}
}
}
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'package:equatable/equatable.dart';
import 'package:fb_auth_provider/models/custom_error.dart';
import '../../models/user_model.dart';
enum ProfileStatus {
initial,
loading,
loaded,
error,
}
class ProfileState extends Equatable {
final ProfileStatus profileStatus;
final User user;
final CustomError error;
ProfileState({
required this.profileStatus,
required this.user,
required this.error,
});
factory ProfileState.initial() {
return ProfileState(
profileStatus: ProfileStatus.initial,
user: User.initialUser(),
error: CustomError(),
);
}
List<Object> get props => [profileStatus, user, error];
bool get stringify => true;
ProfileState copyWith({
ProfileStatus? profileStatus,
User? user,
CustomError? error,
}) {
return ProfileState(
profileStatus: profileStatus ?? this.profileStatus,
user: user ?? this.user,
error: error ?? this.error,
);
}
}
getProfile 함수 호출할거니까 instance로 받아옴.getProfile 은 특정 유저의 정보를 가져오니까 매개변수로 uid를 받아옴.import 'package:flutter/foundation.dart';
import '../../models/custom_error.dart';
import '../../models/user_model.dart';
import '../../repositories/profile_repository.dart';
import 'profile_state.dart';
class ProfileProvider with ChangeNotifier {
ProfileState _state = ProfileState.initial();
ProfileState get state => _state;
final ProfileRepository profileRepository;
ProfileProvider({
required this.profileRepository,
});
Future<void> getProfile({required String uid}) async {
_state = _state.copyWith(profileStatus: ProfileStatus.loading);
notifyListeners();
try {
final User user = await profileRepository.getProfile(uid: uid);
_state = _state.copyWith(
profileStatus: ProfileStatus.loaded, user: user); //성공했으니까 새로운걸로 생성
notifyListeners();
} on CustomError catch (e) {
_state = _state.copyWith(profileStatus: ProfileStatus.error, error: e);
notifyListeners();
}
}
}
return MultiProvider(
providers: [
Provider<AuthRepository>(
create: (context) => AuthRepository(
firebaseFirestore: FirebaseFirestore.instance,
firebaseAuth: fbAuth.FirebaseAuth.instance,
),
),
Provider<ProfileRepository>(
create: (context) => ProfileRepository(
firebaseFirestore: FirebaseFirestore.instance,
),
),
StreamProvider<fbAuth.User?>(
create: (context) => context.read<AuthRepository>().user,
initialData: null,
),
ChangeNotifierProxyProvider<fbAuth.User?, AuthProvider>(
create: (context) => AuthProvider(
authRepository: context.read<AuthRepository>(),
),
update: (BuildContext context, fbAuth.User? userStream,
AuthProvider? authProvider) =>
authProvider!..update(userStream),
),
ChangeNotifierProvider<SigninProvider>(
create: (context) => SigninProvider(
authRepository: context.read<AuthRepository>(),
),
),
ChangeNotifierProvider<SignupProvider>(
create: (context) => SignupProvider(
authRepository: context.read<AuthRepository>(),
),
),
ChangeNotifierProvider<ProfileProvider>(
create: (context) => ProfileProvider(
profileRepository: context.read<ProfileRepository>(),
),
),
],