본문 바로가기
programming/Android

[안드로이드/Kotlin] 인스타그램 클론코딩 - 3 (게시물 좋아요, 팔로우)

by 몽구스_ 2021. 5. 28.
728x90

 

 

 

 

좋아요는 한 번 누르면 누른 사람의 정보가 입력되어

그 정보가 있으면 좋아요가 취소되게 해야 한다.

 

viewHolder.detailviewitem_favorite_imageview.setOnClickListener{
          favoriteEvent(position)
}


fun favoriteEvent(position: Int){
      var tsDoc = firestore?.collection("images")?.document(contentUidList[position])
      firestore?.runTransaction{ transaction ->

            var contentDTO = transaction.get(tsDoc!!).toObject(ContentDTO::class.java)

            if(contentDTO!!.favorites.containsKey(uid)){
                contentDTO?.favoriteCount = contentDTO?.favoriteCount!! - 1
                contentDTO?.favorites.remove(uid)
            }else{
                contentDTO?.favoriteCount = contentDTO?.favoriteCount!! + 1
                contentDTO?.favorites[uid!!] = true
            }
            transaction.set(tsDoc, contentDTO)
      }
}

 

저 하트 버튼을 누를 때 onClickListener가 발생한다.

누른 게시물의 position을 전달해준다.

이를 이용해 list에 있던 알맞는 content를 지정해준다.

해당 content의 favorites는 좋아요 누른 유저를 뜻한다.

favorites에 uid가 있으면 이미 좋아요를 눌른 상태니까 favoriteCount - 1을 해주고 uid도 삭제해준다.

아닐 경우에는 좋아요를 누르지 않은 상태니까 반대로 해준다.

 

  if(contentDTOs!![position].favorites.containsKey(uid)){
        //좋아요 누른 상태
        viewHolder.detailviewitem_favorite_imageview.setImageResource(R.drawable.ic_favorite)
  }else{
        //좋아요 안누른 상태
        viewHolder.detailviewitem_favorite_imageview.setImageResource(R.drawable.ic_favorite_border)
  }

위와 비슷하게 이벤트 이후에 상태를 확인하여 아이콘도 바꿔준다.

 

 

 

 

 

다른 유저를 팔로우하면 해야할 일은 두가지다.

1. 그 유저 팔로우버튼에 언팔로우가 보이고 그 유저 팔로워에 1 추가

2. 동시에 내 계정에 팔로잉 1 추가

 

우선 FollowDTO 모델을 생성한다.

 

fun getFollowerAndFollowing(){
        followListenerRegistration = firestore?.collection("users")?.document(uid!!)?.addSnapshotListener{ documentSnapshot, firebaseFirestoreException ->
            if(documentSnapshot == null) return@addSnapshotListener
            var followDTO = documentSnapshot.toObject(FollowDTO::class.java)
            if(followDTO?.followingCount != null){
                fragmentView?.account_tv_following_count?.text = followDTO?.followingCount.toString()
            }
            if(followDTO?.followerCount != null){
                fragmentView?.account_tv_follower_count?.text = followDTO.followerCount.toString()
                if(followDTO?.followers?.containsKey(currentUserUid!!)){
                    fragmentView?.account_btn_follow_signout?.text = getString(R.string.follow_cancel)
                    fragmentView?.account_btn_follow_signout?.background?.setColorFilter(ContextCompat.getColor(activity!!, R.color.colorLightGray), PorterDuff.Mode.MULTIPLY)
                }else if(uid != currentUserUid) {
                    fragmentView?.account_btn_follow_signout?.text = getString(R.string.follow)
                    fragmentView?.account_btn_follow_signout?.background?.colorFilter = null
                }
            }
        }
    }

 

팔로잉/팔로워 상태를 확인하여 유저 화면에서 띄워주는 function이다.
좋아요와 마찬가지로 followDTO?.followers?.containsKey(currentUserUid!!)를 사용해 본인 아이디가 있는지 확인한다.

그리고 아이디가 있다면 언팔로우를,

아이디가 없다면 팔로우를 보여준다.

 

 

 

fun requestFollow(){
        //내계정에 데이터 저장
        var tsDocFollowing = firestore!!.collection("users").document(currentUserUid!!)
        firestore?.runTransaction{ transaction ->
            var followDTO = transaction.get(tsDocFollowing!!).toObject(FollowDTO::class.java)
            if(followDTO == null){
                followDTO = FollowDTO()
                followDTO!!.followingCount = 1
                followDTO!!.followings[uid!!] = true

                transaction.set(tsDocFollowing, followDTO)
                return@runTransaction
            }

            if(followDTO.followings.containsKey(uid)){
                followDTO?.followingCount = followDTO.followingCount - 1
                followDTO?.followings?.remove(uid)
            }else{
                followDTO?.followingCount = followDTO.followingCount + 1
                followDTO?.followings[uid!!] = true
            }
            transaction.set(tsDocFollowing, followDTO)
            return@runTransaction
        }

        //제 3자에게 데이터 저장
        var tsDocFollower = firestore?.collection("users")?.document(uid!!)
        firestore?.runTransaction{ transaction ->
            var followDTO = transaction.get(tsDocFollower!!).toObject(FollowDTO::class.java)
            if(followDTO == null){
                followDTO = FollowDTO()
                followDTO!!.followerCount = 1
                followDTO!!.followers[uid!!] = true

                transaction.set(tsDocFollower, followDTO!!)
                return@runTransaction
            }

            if(followDTO!!.followers.containsKey(currentUserUid)){
                followDTO!!.followerCount = followDTO!!.followerCount - 1
                followDTO!!.followers?.remove(currentUserUid!!)
            }else{
                followDTO!!.followerCount = followDTO!!.followerCount + 1
                followDTO!!.followers[currentUserUid!!] = true
            }
            transaction.set(tsDocFollower, followDTO!!)
            return@runTransaction
        }
    }

데이터를 저장하는 과정은 다음과 같다.

위에서 상대 계정과 내 계정 둘 다 변경해야 한다고 했으니

following / follower를 구분하여 좋아요처럼 데이터를 저장해준다.

 

 

여기서 오류가 났다.

갑자기 앱이 작동되다가 꺼졌다.

 

 

팔로우 팔로잉 오류 해결
var followListenerRegistration: ListenerRegistration? = null

처음에 선언해준다.

 

getFollowerAndFollowing()에서

followListenerRegistration = firestore?.collection("users")~~~~

첫줄에 그냥 firestore로 시작한 부분을 followListenerRegistration으로 지정해준다.

 

override fun onStop() { super.onStop() followListenerRegistration?.remove() }

onStop()을 override 해주어 여기서 remove시켜준다.

이렇게 해서 오류를 해결하였다.

 

 

 

해당 오류 질문글에 남기신 하울님 답변이다.

이 Q&A와 구글링을 참고하여 코드를 수정했다.

 

 



인스타그램 클론코딩 - 1 (로그인)

https://it-mongoose.tistory.com/103


인스타그램 클론코딩 - 2 (게시물 업로드, 프로필사진 등록)

https://it-mongoose.tistory.com/105

 

댓글