Firebase
Published: 2023-02-09 03:18:41

```kotlin
class Utils {
    companion object {
        private const val SECOND_MILLIS = 1000
        private const val MINUTE_MILLIS = 60 * SECOND_MILLIS
        private const val HOUR_MILLIS = 60 * MINUTE_MILLIS
        private const val DAY_MILLIS = 24 * HOUR_MILLIS

        fun getTimeAgo(time: Long): String? {
            val now: Long = System.currentTimeMillis()
            if (time > now || time <= 0) {
                return null
            }

            val diff = now - time
            return if (diff < MINUTE_MILLIS) {
                "just now"
            } else if (diff < 2 * MINUTE_MILLIS) {
                "a minute ago"
            } else if (diff < 50 * MINUTE_MILLIS) {
                (diff / MINUTE_MILLIS).toString() + " minutes ago"
            } else if (diff < 90 * MINUTE_MILLIS) {
                "an hour ago"
            } else if (diff < 24 * HOUR_MILLIS) {
                (diff / HOUR_MILLIS).toString() + " hours ago"
            } else if (diff < 48 * HOUR_MILLIS) {
                "yesterday"
            } else {
                (diff / DAY_MILLIS).toString() + " days ago"
            }
        }
    }
}
```
```kotlin
    inner class PostViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
        fun bind(userPost: Post) {
            val postText: TextView = itemView.findViewById(R.id.postTitle)
            val userText: TextView = itemView.findViewById(R.id.userName)
            val createdAt: TextView = itemView.findViewById(R.id.createdAt)
            val likeCount: TextView = itemView.findViewById(R.id.likeCount)
            val userImage: ImageView = itemView.findViewById(R.id.userImage)
            val likeButton: ImageView = itemView.findViewById(R.id.likeButton)

            postText.text = userPost.text
            userText.text = userPost.createdBy.displayName
            Glide.with(userImage.context).load(userPost.createdBy.imageUrl).circleCrop().into(userImage)
            likeCount.text = userPost.likeBy.size.toString()
            createdAt.text = Utils.getTimeAgo(userPost.createdAt)
            likeButton.setOnClickListener {
                listener.onLikeClicked(layoutPosition)
            }
            val currentUserId = Firebase.auth.currentUser!!.uid
            val isLiked = userPost.likeBy.contains(currentUserId)
            if(isLiked){
                likeButton.setImageDrawable(ContextCompat.getDrawable(likeButton.context, R.drawable.ic_liked))
            }else{
                likeButton.setImageDrawable(ContextCompat.getDrawable(likeButton.context, R.drawable.ic_unlike))
            }
        }
    }

----
----
interface IPostAdapter{
    fun onLikeClicked(position: Int)
}
```

```kotlin
    private var db: FirebaseFirestore = FirebaseFirestore.getInstance()
    private fun getFirebasePostData() {
        db = FirebaseFirestore.getInstance()
        val postCollections = db.collection("posts")
        postCollections.orderBy("createdAt", Query.Direction.DESCENDING)
            .addSnapshotListener { snapshot, e ->
                if (e != null) {
                    Log.w(TAG, "Listen failed.", e)
                    return@addSnapshotListener
                }

                if (snapshot != null) {
                    for (dc: DocumentChange in snapshot.documentChanges) {
                        if (dc.type == DocumentChange.Type.ADDED) {
                            userPostList.add(dc.document.toObject(Post::class.java))
                        }
                    }
                    postAdapter.notifyDataSetChanged()
                }
            }
    }
```



like

```kotlin
    override fun onLikeClicked(position: Int) {

        userPostId = arrayListOf()

        // Retrieve the data from the Firebase collection
        val postsRef = db.collection("posts")
        GlobalScope.launch {
            postsRef.orderBy("createdAt", Query.Direction.DESCENDING).get()
                .addOnSuccessListener { QuerySnapshot ->
                    for (document in QuerySnapshot) {
                        userPostId.add(document)
                    }
                    val selectedItem = userPostId[position]

                    // retrieve the fields of the clicked document using the documentId
                    val text = selectedItem.get("text")
                    val title = selectedItem["title"] as String
                    val imageUrl = selectedItem.get("imageUrl")

                    postDao = PostDao()
                    postDao.updateLike(selectedItem)

                    Log.e(TAG, selectedItem.toString())
                    // Notify the adapter that the data has changed
                    postAdapter.notifyDataSetChanged()
                }.await()
        }

    }
```

```kotlin
    fun updateLike(selectedPost: DocumentSnapshot){
        val currentUserId = auth.currentUser!!.uid
        val post = selectedPost.toObject(Post::class.java)
        val isLiked = post!!.likeBy.contains(currentUserId)

        if(isLiked){
            post.likeBy.remove(currentUserId)
        }else{
            post.likeBy.add(currentUserId)
        }
        postCollections.document(selectedPost.id).set(post)
    }
```

To access a specific document from a Firestore query result, you can use the getDocuments() method on the query result object and iterate over the list of documents until you find the one with the matching position.
```kotlin
val postsRef = FirebaseFirestore.getInstance().collection("posts")
postsRef.orderBy("createdAt", Query.Direction.DESCENDING).get()
    .addOnSuccessListener { result ->
        val documents = result.documents
        for ((index, document) in documents.withIndex()) {
            if (index == position) {
                // The document with the matching position has been found
                val selectedDocument = document
                // Do something with the selected document...
                break
            }
        }
    }
    .addOnFailureListener { exception ->
        // Handle the error...
    }
```

retrieve the data from the Firebase collection and add each document to this list. The list is then used to populate the RecyclerView with the data.

```kotlin
val postsList = mutableListOf<DocumentSnapshot>()

// Retrieve the data from the Firebase collection
val postsRef = firebaseFirestore.collection("posts")
postsRef.orderBy("createdAt", Query.Direction.DESCENDING).get()
    .addOnSuccessListener {
        for (document in it) {
            postsList.add(document)
        }
        // Notify the adapter that the data has changed
        recyclerViewAdapter.notifyDataSetChanged()
    }

```
you can access the position of the clicked item and use that to retrieve the corresponding document from the Firebase collection.

```kotlin
recyclerView.addOnItemTouchListener(
    RecyclerItemClickListener(context, recyclerView, object : RecyclerItemClickListener.OnItemClickListener {
        override fun onItemClick(view: View, position: Int) {
            val selectedDocument = postsList[position]
            val documentId = selectedDocument.id
            // retrieve the fields of the clicked document using the documentId
            val text = selectedDocument.get("text")
            val imageUrl = selectedDocument.get("imageUrl")
            // Do something with the selected document's fields...
        }
    })
)
```

```kotlin
        CoroutineScope(Dispatchers.IO).launch {
            val post = postDao.postCollections.document(postId).get().await().toObject(Post::class.java)
            val messageToId = post?.createdBy?.uid
            val messageToName = post?.createdBy?.displayName
            withContext(Dispatchers.Main){
                val action = HomeFragmentDirections.actionHomeFragmentToChatFragment(messageToId!!, messageToName!!)
                findNavController().navigate(action)
            }
        }
```

```kotlin
        postDao.postCollections.document(postId).get().addOnSuccessListener {
            val post = it.toObject(Post::class.java)
            if (post != null) {
                val messageToId = post.createdBy.uid
                val messageToName = post.createdBy.displayName
                val action = HomeFragmentDirections.actionHomeFragmentToChatFragment(messageToId, messageToName!!)
                findNavController().navigate(action)
            }
        }
```