Topic = currenUser UID가 포함된 Firestore Data를 가져와보자
이전 게시글에서 데이터 저장하기에 이어서 진행
게시글 데이터 불러오기
Firestore DB
Firestore 데이터 저장코드
db.collection("Posts")
.add(post)
.addOnSuccessListener {
Log.d("xxxx", "postUpload: added with : ${it}")
requireActivity().supportFragmentManager.beginTransaction().replace(R.id.main_frame_layout,HomeFragment()).commit()
}
- 게시글을 DB에 저장할 때 위와 같이 Data를 저장해주었는데 Documents의 id를 별도로 지정해주지 않아서 자동으로 랜덤한 id가 생성된 것을 확인할 수 있다.
그렇다면 랜덤으로 생성된 Documents에 특정 UID가 Field에 포함된 데이터를 확인하여서 나머지 데이터도 가져올 수 있도록 해야한다.
Firestore 데이터 불러오기 쿼리
private fun downloadPostInfo() {
db.collection("Posts")
.whereEqualTo("uid", "${auth.currentUser!!.uid}")
.get()
.addOnSuccessListener { querySnapshot ->
if (!querySnapshot.isEmpty) {
// 현재 로그인 한 UID 가 포함된 Documents 데이터
val documentSnapshot = querySnapshot.documents
}
}
.addOnFailureListener {
Log.d("xxxx", " Failure : $it ")
}
}
- 위와 같은 쿼리를 사용하여 지정한 Collection 내의 모든 값 중에서 현재 로그인되어 있는 UID가 포함된 Documents를 가져오도록 할 것이다.
- 쿼리에 대한 자세한 내용은 별도의 게시글에서 정리해볼 예정
MyPostFeedAdapter
❌ 10.28 추가 - Bind에서 Storage의 이미지를 가져올 경우 스크롤 할 때마다 Storage에서 이미지를 새로 불러오기 때문에 이미지가 뒤늦게 나타나는 문제가 발생하므로 아래 게시글에서 작성한 방식으로 수정
ViewHolder
private val storage = Firebase.storage
inner class MyPostFeedRcvViewHolder(binding: RcvItemPostBinding) :
RecyclerView.ViewHolder(binding.root) {
val postTitle: TextView = binding.postTitle
val postDesc: TextView = binding.postDesc
val postPrice: TextView = binding.postPrice
val postCategory: TextView = binding.postCategory
val postImg: ImageView = binding.postImg
fun bind(imagePath : String) {
storage.reference.child("post").child("$imagePath").downloadUrl.addOnSuccessListener { uri ->
Glide.with(itemView)
.load(uri)
.into(postImg)
Log.d("xxxx", " adapter bind: $uri")
}.addOnFailureListener {
Log.d("xxxx", " adapter bind Failure $it")
}
}
}
...
}
- Inner class ViewHolder의 bind() 함수 내부에서 게시글의 이미지에 해당하는 Storage의 path 값의 의미지를 Rcv Item의 이미지 뷰에 적용시켜준다.
Rcv Adapter - onBindViewHolder()
override fun onBindViewHolder(holder: MyPostFeedRcvViewHolder, position: Int) {
val post = currentList[position]
val positionItem = currentList[position]
holder.apply {
postCategory.text = "카테고리 : ${positionItem.category}"
postTitle.text = positionItem.title
postDesc.text = positionItem.desc
postPrice.text = positionItem.price
}
holder.bind(positionItem.imgs.First())
Log.d("xxxx", "onBindViewHolder: ${positionItem.imgs.last()}")
}
- 각 Position에 해당하는 Item에 일치하는 데이터를 적용시켜준다.
Firestore 데이터에 넣어준 이미지 경로의 값이 3개라는 가정이면 이미지를 선택할 때 2,1,0 순서로 들어가기 때문에 게시글에 이미지를 선택할 때 가장 먼저 선택한 이미지가 대표이미지로 보이도록 마지막에 해당하는 img.last() 로 Index 지정해준다.- Android studio에서 기본적으로 제공하는 IntentACTION_PICK 과 Photo Picker는 클릭한 순서대로 List에 저장되는 기능을 제공하지 않는다. 이미지를 클릭할 때 클릭한 순서대로 List에 담는 방법 학습하게 되면 추가 예정.
MyFeedPostFragment.kt
class MyPostFeedFragment : Fragment() {
private var _binding: FragmentMyPostFeedBinding? = null
private val binding get() = _binding!!
private lateinit var auth: FirebaseAuth
private lateinit var db: FirebaseFirestore
// 내 게시글 RecyclerView Adpapter
private lateinit var myPostFeedAdapter: MyPostFeedAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
auth = Firebase.auth
db = Firebase.firestore
}
- 내 게시글 목록 Fragment - 현재 로그인 되어져 있는 사용자의 UID 값과 Firestore DB의 데이터가 필요하므로 Firebase 객체 선언 및 초기화 해준다
Firestore 데이터 가져오기
private fun downloadPostInfo() {
db.collection("Posts")
.whereEqualTo("uid", "${auth.currentUser!!.uid}")
.get()
.addOnSuccessListener { querySnapshot ->
if (!querySnapshot.isEmpty) {
val documentSnapshot = querySnapshot.documents
Log.d("xxxx", " testA[0].data : ${documentSnapshot[0].data} ")
val rcvList: MutableList<Post> = mutableListOf()
for (document in documentSnapshot) {
rcvList.add(
Post(
document.data?.get("uid") as String,
document.data?.get("title") as String,
document.data?.get("price") as String,
document.data?.get("category") as String,
document.data?.get("address") as String,
document.data?.get("deadline") as String,
document.data?.get("desc") as String,
document.data?.get("imgs") as List<String>,
document.data?.get("uploadDate") as String,
)
)
}
Log.d("xxxx", " result : $rcvList")
myPostFeedAdapter.apply {
submitList(rcvList)
notifyDataSetChanged()
}
}
}
.addOnFailureListener {
Log.d("xxxx", " Failure : $it ")
}
}
- whereEqualTo 쿼리를 통해 currentUser의 UID가 포함된 Documents 를 가져온다.
- Document에서 필요한 Filed 값들을 Post Data Model의 형식으로 RecyclerView List에 추가해준다.
- UID 에 해당하는 값을 찾고 순서대로 정렬하는 복합쿼리에 대해서 추가 학습 후 정렬기능 추가예정.
Rcv Adapter 연결해주기
private fun setupRcv() {
myPostFeedAdapter = MyPostFeedAdapter(object : PostClick {
override fun postClick(post: Post) {
Log.d("xxxx", "postClick: ")
}
})
binding.postFeedRcv.apply {
setHasFixedSize(true)
layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
adapter = myPostFeedAdapter
addItemDecoration(DividerItemDecoration(context, LinearLayout.VERTICAL))
}
downloadPostInfo()
}
- 정의해둔 setupRcv() 함수를 onCreateView() 내부에서 실행할 수 있도록 해주면 된다.
완성 화면
MyFeedPostFragment 전체코드
class MyPostFeedFragment : Fragment() {
private var _binding: FragmentMyPostFeedBinding? = null
private val binding get() = _binding!!
private lateinit var auth: FirebaseAuth
private lateinit var db: FirebaseFirestore
private lateinit var myPostFeedAdapter: MyPostFeedAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
auth = Firebase.auth
db = Firebase.firestore
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentMyPostFeedBinding.inflate(inflater, container, false)
setupRcv()
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.backButtonWritepage.setOnClickListener {
requireActivity().supportFragmentManager.beginTransaction().replace(R.id.main_frame_layout,MyPageFragment()).commit()
}
}
private fun downloadPostInfo() {
db.collection("Posts")
.whereEqualTo("uid", "${auth.currentUser!!.uid}")
.get()
.addOnSuccessListener { querySnapshot ->
if (!querySnapshot.isEmpty) {
val documentSnapshot = querySnapshot.documents
Log.d("xxxx", " testA[0].data : ${documentSnapshot[0].data} ")
val rcvList: MutableList<Post> = mutableListOf()
for (document in documentSnapshot) {
rcvList.add(
Post(
document.data?.get("uid") as String,
document.data?.get("title") as String,
document.data?.get("price") as String,
document.data?.get("category") as String,
document.data?.get("address") as String,
document.data?.get("deadline") as String,
document.data?.get("desc") as String,
document.data?.get("imgs") as List<String>,
document.data?.get("uploadDate") as String,
)
)
}
Log.d("xxxx", " result : $rcvList")
myPostFeedAdapter.apply {
submitList(rcvList)
notifyDataSetChanged()
}
}
}
.addOnFailureListener {
Log.d("xxxx", " Failure : $it ")
}
}
private fun setupRcv() {
myPostFeedAdapter = MyPostFeedAdapter(binding.root,object : PostClick {
override fun postClick(post: Post) {
Log.d("xxxx", "postClick: ")
}
})
binding.postFeedRcv.apply {
setHasFixedSize(true)
layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
adapter = myPostFeedAdapter
addItemDecoration(DividerItemDecoration(context, LinearLayout.VERTICAL))
}
downloadPostInfo()
}
}
[ A. 오늘 복습한 내용 / B. 다음에 학습할 내용 ]
A. Firesbase DB 저장 및 불러오기 복습
B. ★ Firestore 쿼리를 통한 여러가지 데이터 정렬 및 다운로딩 방법에 대해서 배워보자
B. Firebase 속도가 느린건지 내가 뭘 잘못한건지 데이터 불러오는 속도가 느린데 이 문제를 개선할 방법
[오류,에러 등등]
1. 이미지 선택 시 선택한 순서대로 List에 들어가지 않는 문제
- Listener에서 받아오는 순간부터 순서가 정해져서 들어오기 때문에 별도로 이미지 피커 Library나, Activity로 만드는 방법이 필요하다?
- 해결 시 추가 예정
[느낀 점]
1. Firebase 전체적인 이해도 + 5 [ 7 / 100 ]
2. Firebase DB는 쿼리를 잘 사용하는 것이 중요해 보인다.
3. 학습 속도가 느린 것 같아서 걱정이다.
[Reference]
// Firestore
https://firebase.google.com/docs/firestore/quickstart?hl=ko#kotlin+ktx
https://firebase.google.com/docs/firestore/query-data/queries?hl=ko#kotlin+ktx_1
'TIL' 카테고리의 다른 글
[TIL] Kotlin Firestore, Storage [ 3 ] 게시글 디테일 페이지로 이동하기, 수정하기 ( 좋아요 기능 ) (2) | 2023.10.29 |
---|---|
[TIL] Kotlin Storage를 Adapter의 내부에서 호출 시 문제 (1) | 2023.10.28 |
[TIL] Kotlin Firebase Firestore, Storage [ 1 ] 이미지가 포함된 게시글 쓰기 (0) | 2023.10.21 |
[TIL] Kotlin Firebase Storage 단일, 복수 이미지 넣고 불러오기 (1) | 2023.10.20 |
[TIL] Kotlin Firebase - Realtime Database [ 2 ] 저장된 데이터Listener로 가져오기 (5) | 2023.10.19 |