하아... 누가 간단한 KiCad 알바 좀 하자고 해서 했는데;;; 2주를 날렸어... ㅠㅠ 화딱지나... 암튼 앱 개발 속행!!
좋아요! 기능은 매우 보편적이지.. 그런데 이게 은근히 짜증나... 우선 누가 좋아요를 눌렀는지 기록해야하고, 그리고 몇개의 좋아요인지도 알아내야 해. 난 firestore를 사용중이니 그걸 기준으로 하자면 단순하게 좋아요를 누른 사람을 기록하는 건 간단해. 그냥 sub collection 하나 만들고 user id를 포함한 문서를 계속 더하거나 빼면 되니까.
그런데 말이지.... 다른 DB는 모르겠지만 적어도 firestore에서는 좋아요를 카운트하는 일은 간단하지가 않아;; 왜냐하면 firestore에서 허용되는 문서 업데이트 주기가 초당 1회이기 때문이지;; 전세계에서 BTS팬들이 BTS글에다가 좋아요를 누른다고 생각해봐...ㅎㄷㄷ 생각만 해도 끔찍... 당연히 이런 문제를 구글형들도 알고 있어. 그래서 이럴때 쓰라고 Distributed Counter라는 건 제안해 주셨어.👇👇
2022.11.28 - [Cloud services/Google Cloud] - [Firestore] Distributed Counter
위 글에서 소개되어 있는데로 난 distributed counter extension을 설치한 상태로 해당 기능을 구현해놨으니까 참고해.
간단하게 extension이 동작하는 방식을 요약하자면 A라는 firestore 문서에다가 "_counter_shards_"라는 subcollection을 만들고 더하거나 빼고 싶은 카운터 이름을 넣어서 문서를 생성하면 A 문서의 카운터에 합산이 된다 이거지. ㅋㅋㅋ 개소리냐고? 그림 ㄱㄱ
그림 보면 알겠지? 아무 문서에다가 _counter_shards_라는 서브 collection 만들고 문서 추가하면 상위 문서의 counter에 합산돼.
이것만 이해하고 있으면 구현은 쏘 이지!👇
void onLikeButtonPress() {
if (!likePressed) {//좋아요 버튼이 안눌려있으면
//likeUserList에다가 현재 userid로 document 추가.
likeUserListColRef(cardId).doc(firebaseAuth.currentUser!.uid).set(
ModelUserList(
userId: firebaseAuth.currentUser!.uid,
createdAt: Timestamp.now()));
//_counter_shards_ subcollection에 likeCounter:1 포함하여 문서 추가
userInsightCardColRef()
.doc(cardId)
.collection("_counter_shards_")
.add({"likeCounter": 1});
//화면에 보이는 likeCounter++;
currentLikeCounter++;
likePressed = !likePressed;
} else {// 좋아요 버튼이 눌려 있나?
//likeUserList에서 현재 user 문서 삭제!
likeUserListColRef(cardId).doc(firebaseAuth.currentUser!.uid).delete();
//_counter_shards_ subcollection에 likeCounter:-1 포함하여 문서 추가
userInsightCardColRef()
.doc(cardId)
.collection(SHARD_COLLECTION_ID)
.add({"likeCounter": -1});
//화면에 보이는 likeCounter--;
currentLikeCounter--;
likePressed = !likePressed;
}
}
이렇게 하여 초당 1만회까지 업데이트가 가능한 좋아요 기능 완성!... 완성? 놉 아니지. 위에서처럼 여러가지 firestore 동작을 할 때는 transaction이나 batch를 써야해. 난 transaction을 사용할건데 transaction은 여러가지 동작중에서 어느 한 동작을 실패하면 전체를 되돌리기 때문에 에러 처리가 매우 간단해지지.👇👇
void onLikeButtonPress() {
if (!likePressed) {
likePressed = !likePressed;
firestore.runTransaction(
(transaction) async {
transaction.set(
likeUserListColRef(cardId).doc(firebaseAuth.currentUser!.uid),
ModelUserList(
userId: firebaseAuth.currentUser!.uid,
createdAt: Timestamp.now()));
transaction.set(
userInsightCardColRef()
.doc(cardId)
.collection(SHARD_COLLECTION_ID)
.doc(),
{"likeCounter": 1});
},
).then((value) {
currentLikeCounter++;
}, onError: (e) => throw (e));
} else {
likePressed = !likePressed;
firestore.runTransaction(
(transaction) async {
transaction.delete(
likeUserListColRef(cardId).doc(firebaseAuth.currentUser!.uid));
transaction.set(
userInsightCardColRef()
.doc(cardId)
.collection(SHARD_COLLECTION_ID)
.doc(),
{"likeCounter": -1});
},
).then((value) {
currentLikeCounter--;
}, onError: (e) => throw (e));
}
}
벌써 12월이네 ㅠㅠ 빨리 빨리 완성하자! 아자아자!
'Flutter > Flutter Project' 카테고리의 다른 글
[소셜차트] 앱 제작기 #15. Full Text search (2) | 2023.01.02 |
---|---|
[소셜차트] 앱 제작기 #14. 프로필 수정 화면 (0) | 2022.12.07 |
[소셜차트] 앱 제작기 #12. 댓글 기능 & 기타 잡다! (0) | 2022.11.12 |
[소셜차트] 앱 제작기 #11. 운수 좋은 날.. (1) | 2022.11.09 |
[소셜차트] 앱 제작기 #10. Tap to scroll top (0) | 2022.11.08 |