Flutter Firebase 데이터 update (데이터 수정)

2024. 11. 1. 05:58Flutter

 

저번 블로그에 이어서 이번 블로그에선

Firebase에 저장된 데이터를 수정하는 방법에 대해 정리를 해보려고 한다

상황을 간단하게 설명하자면

userLevel 이라는 컬렉션 내부에

'userLevel' 이라는 필드에 1을 추가해주고

'userExValue'라는 필드를 0으로 수정해주면 된다

즉 레벨 형태로써 userExValue의 값이 100이상이 될 경우 

레벨을 1업 하고 경험치를 초기화 하는 것이다

 

 

DataSource

 

가장 먼저 파이어베이스에서 나의 userUid를 가지고 있는 문서를 찾아주고

수정하는 코드를 구현한다

 

//userUid에 맞는 데이터 가져와서 레벨 1 올리고 경험치 초기화하기
  Future<void>updateUserLevel(String userUid)async{
    QuerySnapshot querySnapshot = await firestore.collection('userLevel')
        .where('userUid', isEqualTo: userUid)
        .get();
    
    if (querySnapshot.docs.isNotEmpty) {
      DocumentSnapshot document = querySnapshot.docs.first;

      await firestore.collection('userLevel').doc(document.id).update({
        'userExValue' : 0,
        'userLevel' : FieldValue.increment(1),
      });
    }  
  }

 

우선 userUid를 가지고 문서를 찾아준 다음

if문을 활용하여 해당 문서가 null이 아닐경우 데이터를 업데이트 시켜주기로 했다

 

사실 userExValue나 userLevel도 int값으로 입력 받을 수 있지만

이게 동작하게 된다면 

당연하게도 레벨은 +1만 하면되고

경험치는 0으로 초기화만 하면 되기 때문에 이렇게 구현했다!

 

 

 

Repository

다음은 Repository이다!

 

//userUid에 맞는 데이터 가져와서 레벨 1 올리고 경험치 초기화하기
  Future<void>updateUserLevel(String userUid)async{
    await dataSource.updateUserLevel(userUid);
  }

 

이 부분에서 특별히 작업한 것이 없기 때문에 넘어가도록 하겠다 ㅎㅎ

 

 

Provider

 

전에도 설명했지만 나는 riverPod을 활용하여 구현했다

//userUid에 맞는 데이터 가져와서 레벨 1 올리고 경험치 초기화하기
final updateUserLevelProvider = FutureProvider.autoDispose.family<void, String>((ref, userUid)async{
  await ref.watch(userLevelRepoProvider).updateUserLevel(userUid);
});

 

이 부분도 이렇게 구현을 해주었다!

(autoDispose를 활용하여 FutureProvider가 호출될 때마다 새로 값을 생성하게끔 해주었다)

 

 

적용하기

 

void showCheckBoxDialog(BuildContext context, WidgetRef ref, int index, List<AddWorkModel> todo) {
    final todoOne = todo[index];
    final userLevel = ref.watch(getUserLevel);
    String truncateWithEllipsis(int cutoff, String text) {
      if (text.length <= cutoff) {
        return text;
      } else {
        return '${text.substring(0, cutoff)}...';
      }
    }

    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (context) {
      return userLevel.when(
          data: (level){
            return DialogComponents(
                richContent: [
                  TextSpan(
                      text: "'",
                      style: AppTextStyles.systemBold(size: 20, color: AppColors.dark(4))
                  ),
                  TextSpan(
                      text: truncateWithEllipsis(13, todoOne.todoName),
                      style: AppTextStyles.systemBold(size: 20, color: AppColors.green(8))
                  ),
                  TextSpan(
                      text: "'",
                      style: AppTextStyles.systemBold(size: 20, color: AppColors.dark(4))
                  ),
                  TextSpan(
                      text: "을(를)\n모두 완료했나요?",
                      style: AppTextStyles.systemBold(size: 20, color: AppColors.dark(4))
                  ),
                ],
                leftButtonText: '아니요',
                rightButtonText: '완료',
                clickLeft: (){
                  Navigator.pop(context);
                },
                clickRight: ()async{
                  Navigator.pop(context);
                  ref.watch(updateTodoDoneFalse(todoOne.todoId));
                  fivePerBatteryDialog(context);
                  if (level!.userExValue >= 95) {
                    ref.watch(updateUserLevelProvider(todoOne.userUid));
                  }  else{
                    ref.watch(updateFivePerUserExpProvider(todoOne.userUid));
                  }
                }
            );
          },
          error: (error, stack) => Center(child: Text("Error : $error"),),
          loading: () => Center(child: CircularProgressIndicator(),)
      );
    });
  }

 

 

좀 길다,,, 우선 간단히 설명을 하자면

Dialog를 띄워서 오른쪽을 클릭하면 경험치를 5 증가시키거나
만약 경험치가 100이 된다면 경험치를 0으로 수정하고

레벨을 +1 해주는 코드이다

 

 

final userLevel = ref.watch(getUserLevel);

이 변수를 통해 현재 유저의 userLevel 정보를 가져오고

 

 

userLevel.when(

위의 코드를 사용하여 현재 유저의 경험치 정보를 받아볼 수 있게 한다

 

 

clickRight: ()async{
  Navigator.pop(context);
  ref.watch(updateTodoDoneFalse(todoOne.todoId));
  fivePerBatteryDialog(context);
  if (level!.userExValue >= 95) {
    ref.watch(updateUserLevelProvider(todoOne.userUid));
  }  else{
    ref.watch(updateFivePerUserExpProvider(todoOne.userUid));
  }
}

 

이제 여기서 userExValue를 if문을 활용해서 비교하고 지금은 5만 증가시키기 때문에

95이상일 경우에는 경험치를 초기화하고 레벨 +1이 되게끔 코드를 구현하였다

 

하지만 만약 95가 되지 않을 경우에는 경험치를 5만큼 추가하게끔 해주었다!!

 

 

다음 블로그는 데이터 받아오는 걸 써보도록 해야겠다!

얼른 다시 프로젝트 하러 가야ㅈㅣ,,,,