지난 시간에 설정했던 내 주소 [경기도 성남시 수정구 창곡동]와 범위 [도(시)/ 구(시/군)/ 동명(읍/명)]를 Firestore db의 'User' collection에 저장하려고 한다. 우선, 회원정보를 UserProvider에 저장해야한다.
1. 회원가입
validation 검사→authentication 추가→firestore db 'User' collection에 삽입 (set()사용)→UserProvider에 저장
_tryValidation(); //validation 검사
try {
final newUser = await _authentication
.createUserWithEmailAndPassword( //authentication 추가
email: userEmail,
password: userPassword,
);
if (newUser.user != null) { //firestore 추가
await FirebaseFirestore.instance
.collection("User")
.doc(newUser.user!.uid)
.set({
"Email": userEmail,
"Password": userPassword,
"NickName": userNickName,
"Scope": "",
"Ingredient": [],
"MyRecipes": [],
"Location": "",
"Post": "",
},
).onError((e, _) =>
print("Error writing document: $e"));
_userProvider.signup(newUser.user!.uid,
userEmail, userPassword, userNickName); //userProvider 저장
2. 로그인
validation 검사→authentication 이용해 존재 확인→ 'User' collection에서 uid를 이용해 해당 유저를 찾아 UserProvider에 저장 (get()사용)
onTap: () async {
_tryValidation(); //validation 검사
try {
final newUser = await _authentication
.signInWithEmailAndPassword( //authentication 이용해서 회원 찾기
email: userEmail,
password: userPassword,
);
if (newUser.user != null) {
var result = await FirebaseFirestore.instance
.collection("User")
.doc(newUser.user!.uid);
await result.get().then((value) => { //firestore user 찾기
_userProvider.login( //userProvider 저장
newUser.user!.uid,
value['Email'].toString(),
value['Password'].toString(),
value['NickName'].toString(),
value['Location'].toString(),
value['Scope'].toString(),
value['Ingredient'].cast<String>(),
value['MyRecipes'].cast<String>(),
value['Post'].cast<String>(),
),
});
Provider란?
Flutter는 공식문서가 굉장히 자세하고 친절하게 나와있어 공식문서를 보면서 따라해도 된다.
하지만 영어를 못하는 나같은 사람을 위해 ...
위 벨로그를 참고하면 프로바이더를 생성하는 코드는 다음과 같다.
// 프로바이더 인스턴스 생성
late UserProvider _userProvider;
// 프로바이더 사용
_userProvider = Provider.of<UserProvider>(context);
// set
String email = _userProvider.email;
// get
_userProvider.email = _emailConroller.text;
3. UserProvider
class UserProvider extends ChangeNotifier {
String _uid="";
String _email = ""; //사용자 이메일
String _password = ""; //사용자 비밀번호
String _location=""; //사용자 위치 (경기도 성남시 수정구 창곡동)
String _nickname=""; //사용자 닉네임 (게시글 작성 시)
String _scope=""; //사용자 위치 범위
List<String> _ingredients=[]; //사용자 재료
List<String> _recipes=[]; //사용자 스크랩한 레시피
List<String> _posts=[]; //사용자 게시글
String get uid=>_uid;
String get email => _email;
String get password => _password;
String get location=>_location;
String get nickname => _nickname;
String get scope=>_scope;
List<String> get ingredients=>_ingredients;
List<String> get recipes=>_recipes;
List<String> get posts=>_posts;
void signup(String _uid, String _email, String _password, String _nickname){
this._uid=_uid;
this._email=_email;
this._password=_password;
this._nickname=_nickname;
this._location="";
this._scope="";
this._ingredients=[];
this._recipes=[];
this._posts=[];
notifyListeners();
}
void login( String _uid, String _email, String _password, String _nickname, String _location,
String _scope, List<String> _ingredients, List<String> _recipes, List<String> _posts) {
this._uid=_uid;
this._email=_email;
this._password=_password;
this._nickname=_nickname;
this._location=_location;
this._scope=_scope;
this._ingredients=_ingredients;
this._recipes=_recipes;
this._posts=_posts;
notifyListeners();
}
void set uid(String input_uid){
_uid=input_uid;
notifyListeners();
}
void set email(String input_email) {
_email = input_email;
notifyListeners();
}
void set password(String input_password) {
_password = input_password;
notifyListeners();
}
void set location(String input_location){
_location=input_location;
notifyListeners();
}
void set nickname(String input_nickname){
_nickname=input_nickname;
notifyListeners();
}
void set scope(String input_scope){
_scope=input_scope;
notifyListeners();
}
void set ingredients(List<String> input_ingredients){
_ingredients=input_ingredients;
notifyListeners();
}
void set recipes(List<String> input_recipes){
_recipes=input_recipes;
notifyListeners();
}
void set posts(List<String> input_posts){
_posts=input_posts;
notifyListeners();
}
void addIngredient(List<String> input_ingredients){ //재료추가할 때는 list로 받기
_ingredients.addAll(input_ingredients);
notifyListeners();
}
void scrapRecipe(String recipeCode){
_recipes.add(recipeCode);
notifyListeners();
}
void addPost(String postId){
_posts.add(postId);
notifyListeners();
}
}
4. 내 주소와 범위 설정하기
userProvider의 location와 scope 값 update→firestore에 변경된 값 update
TextButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
}
_userProvider.scope=selectedValue.toString();
if (selectedValue != null) {
await FirebaseFirestore.instance
.collection("User")
.doc(_userProvider.uid)
.set({
"Location": _userProvider.location,
"Scope": selectedValue.toString(),
}, SetOptions(merge: true));
}
},
이때, 중요한 점은 SetOptions(merge: true))!
이걸 추가하지 않으면 덮어쓰기가 되어서 User collection에 나머지 정보는 다 날라가고 location와 scope 값만 달랑 남게 된다. 당황하지 말고 뒤에 SetOptions(merge:true)만 붙여주면 된다!
'Flutter' 카테고리의 다른 글
Flutter 게시글 클릭해서 상세 조회하기 (0) | 2022.11.27 |
---|---|
Flutter Stream+ListView 이용해서 게시글 목록 가져오기 (0) | 2022.11.27 |
Flutter 내 동네 설정하기 -1 (0) | 2022.11.19 |