How to create imageview in itemCard of Recyclerview as many as ArrayList size from Firestore? Android Kotlin - android

I want to create imageview as many as arraylist size. I have images arrayList type of String which are image strings from Firestore. I get the data and give it to Recyclerview, but I don't know how to create imageview as size of imageList in item.
DataClass
data class AjansGruplariChat(
val images: ArrayList<String?>,
val isRead: ArrayList<String?>,
val message: String,
val selection: String,
val sender: String,
val timeStamp: String)
Firestore Data
Firestore Repo
firebaseFireStore.collection("Agencies").document(docId)
.collection("Chat")
.addSnapshotListener { value, error ->
if (error == null) {
val documents2 = value?.documents
if (documents2 != null) {
val list = mutableListOf<AjansGruplariChat>()
for (document2 in documents2) {
val images = document2.get("images") as ArrayList<String?>
val isRead = document2.get("isRead") as ArrayList<String?>
val message = document2.get("message").toString()
val selection = document2.get("selection").toString()
val sender = document2.get("sender").toString()
val timeStamp = document2.get("timeStamp").toString()
val newAjansGrupChat = AjansGruplariChat(images, isRead, message, selection, sender, timeStamp)
list.add(newAjansGrupChat)
}
ajansChatListRepo.value = list
}
}
}
ItemCard

Related

Values are not added in an array instead it keeps updating value at 0th index in Firebase Firestore

On clicking like button , it is not either increasing like count in UI nor adding a userid in likes array. It is not adding a userid into an array instead it is updating value at 0th index. I am attaching photos of logic to add values in array in firestore.
I have also added the project on github. Please take a look at it for more clearification.
https://github.com/Anshi10/Social-Media-App
Post data class which has array of user ids which liked a post.
data class Post(
val text : String = "" ,
val createdBy : user = user() ,
val createdAt : Long = 0L ,
val Likes : ArrayList<String> = ArrayList()
)
Post Dao for adding post into firestore and updating likes
class PostDao {
val db = FirebaseFirestore.getInstance()
val PostCollection = db.collection("Post")
val auth = Firebase.auth
fun addPost(text : String){
//!! is to ensure that post is created only when user is logged in otherwise it will count as illegal exception
val currentUserId = auth.currentUser!!.uid
val userdao = userDao()
GlobalScope.launch{
//getuserbyid return task which will turn into object of user data class
val Postuser = userdao.getuserbyId(currentUserId).await().toObject(user::class.java)!!
//this will give the time when the post is created
val currentTime = System.currentTimeMillis()
val post = Post(text,Postuser,currentTime)
PostCollection.document().set(post)
}
}
fun getPostById(postid : String) : Task<DocumentSnapshot>{
return PostCollection.document(postid).get()
}
fun updateLikes(postid: String) {
GlobalScope.launch {
val currentUserid = auth.currentUser!!.uid
val post = getPostById(postid).await().toObject(Post::class.java)!!
val isliked = post.Likes.contains(currentUserid)
if (isliked) {
post.Likes.remove(currentUserid)
} else {
post.Likes.add(currentUserid)
}
PostCollection.document(postid).set(post)
}
Log.d("msg","updateLikes called")
}
}
onBindViewHolder function
override fun onBindViewHolder(holder: PostViewHolder, position: Int, model: Post) {
holder.userName.text = model.createdBy.name
holder.userText.text = model.text
//with(context) load(url) into(view)
Glide.with(holder.userImage.context).load(model.createdBy.imageUrl).circleCrop().into(holder.userImage)
holder.Likecount.text = model.Likes.size.toString()
holder.userTime.text = Utils.getTimeAgo(model.createdAt)
val auth = FirebaseAuth.getInstance()
val currentuserId = auth.currentUser!!.uid
val isliked = model.Likes.contains(currentuserId)
if(isliked){
holder.likeButton.setImageDrawable(ContextCompat.getDrawable(holder.likeButton.context,R.drawable.ic_baseline_favorite_24))
}
else{
holder.likeButton.setImageDrawable(ContextCompat.getDrawable(holder.likeButton.context,R.drawable.unliked))
}
}
}
Firestore structure
first collection named post which contains field createdAt , createdBy,likesCount,text of the post.
second collection named users which contains field id , imageUrl , name

I want to show a data whose values I have determined myself in text

calculateButton.setOnClickListener {
val panelC = binding.panelCount.text.toString()
val panelS = binding.panelSize.text.toString()
val landS = binding.landSlope.text.toString()
val landSi = binding.landSize.text.toString()
val cit = binding.city.text.toString()
val sun = (1000).toInt()
val air = (1.25).toFloat()
val cel = (25).toInt()
val verim = ((sun * air)/ cel).toString().toDouble()
if (panelC.equals("") || panelS.equals("")|| landS.equals("")|| landSi.equals("")||cit.equals("")){
Toast.makeText(requireContext(),"Alanları Doldurunuz.", Toast.LENGTH_SHORT).show()
}
else{
val action = SignUpCalculateFragmentDirections.actionSignUpCalculateFragmentToDataFragment()
Navigation.findNavController(view).navigate(action)
}
val postMap = hashMapOf<String, Any>()
postMap.put("Panel Sayisi",binding.panelCount.text.toString())
postMap.put("Panel Boyutu",binding.panelSize.text.toString())
postMap.put("Arazi Eğimi",binding.landSlope.text.toString())
postMap.put("Arazi Boyutu",binding.landSize.text.toString())
postMap.put("Şehir",binding.city.text.toString())
postMap.put("date", Timestamp.now())
postMap.put("verim",verim.toString().toDouble())
firestore.collection("Posts").add(postMap).addOnFailureListener {
}.addOnFailureListener {
Toast.makeText(requireContext(),it.localizedMessage,Toast.LENGTH_SHORT).show()
}
There is a calculatePage Fragment Codes. On this page, I am trying to make a yield calculation based on the data I receive from the user. However, I need to add the values that are kept constant in the efficiency calculation, such as "sun", "cel", "air" that I defined in the code. I wrote a random operation there as an example. To see if I can write inside the text I'm trying to print without getting any errors. But the app crashed.
private fun getData(){
firestore.collection("Posts").addSnapshotListener { value, error ->
if (error!=null){
Toast.makeText(requireContext(),error.localizedMessage,Toast.LENGTH_SHORT).show()
}else{
if (value !=null){
if (!value.isEmpty){
val documents = value.documents
for (document in documents){
val pc = document.get("Panel Sayisi") as String
val ps = document.get("Panel Boyutu") as String
val ls = document.get("Arazi Eğimi") as String
val lsi = document.get("Arazi Boyutu") as String
val c = document.get("Şehir") as String
val v = document.get("verim") as Double
val post = Post(pc,ps,ls,lsi,c,v)
postArrayList.add(post)
}
}
}
}
val db = FirebaseFirestore.getInstance()
db.collection("Posts").orderBy("date",Query.Direction.DESCENDING).limit(1)
.get()
.addOnCompleteListener {
val result : StringBuffer = StringBuffer()
if (it.isSuccessful){
for (document in it.result){
result.append(document.data.getValue("verim"))
}
verimText.setText(result)
}
}
On this page, I added the values I defined in my class named 'post' to the postList and added them to Firestore.
data class Post(val pc: String, val ps: String, val ls: String, val lsi: String, val c: String, val v : Double)
#ServerTimestamp
var date: Date? = null
This is my post class
The error is like this: java.lang.NullPointerException: null cannot be cast to non-null
type kotlin.Double
As I explained at the beginning of my question, what I am trying to do is using both the data such as "panelCount", "panelSize" that I get from the user and the "sun", "cel", "air" values that are defined as constants, using the "verimText.setText(result)" in the DataFragment page. I need to show this calculation to the user.
The user enters values such as 'Panel Sayisi', 'Panel Boyutu' that should be used while calculating on the calculation page. I need to show this to the user in verimText using both this data and the 'cel', 'sun', 'air' constants that I wrote in the first code.
PS: verim: 20000 value is the result of hypothetical values that I wrote in the first code. In this part, I need to make a calculation using the other data entered by the user and these constant values and show it in the verimText.

how to get position of deleted Firestore Data that have been deleted from console (outside source) to update Or notify the adapter

I have this app that someone can delete his document at any time so if he deletes the document I want every other user to get updated the document has been removed and remove the document from the listView, it's more like a Food Ordering app so the user order could be taking by another Driver so the document will no longer be available for other users, I want to update the recyclerView Whenever a user deletes a document, so how to get the position without clicking how to detect that change to get the position, Sorry if I couldn't explain much I'm Using Groupie Adapter
val ref = firestore.collection("orders").whereNotEqualTo("userUid", uid)
val adapter = GroupAdapter<GroupieViewHolder>()
ref.addSnapshotListener { value, error ->
if (error != null){
return#addSnapshotListener
}
value?.documentChanges?.forEach {
if (it.type == DocumentChange.Type.ADDED) {
val userUid = it.document.data.get("userUid") as String
val userPhone = it.document.data.get("phone") as String
val userName = it.document.data.get("name") as String
val time = it.document.data.get("time") as String
val marketName = it.document.data.get("marketName") as String
val amount = it.document.data.get("amount") as String
val storeimgUrl = it.document.data.get("storeImg") as String
val order = it.document.data.get("order") as String
val userImg = it.document.data.get("userImg") as String
adapter.add(DriverOrders(userUid, userPhone, userName, time, marketName, amount, storeimgUrl, order, userImg))
adapter.notifyDataSetChanged()
}
if(it.type == DocumentChange.Type.REMOVED){
// here Wher I'm trying to get the position of deleted Or removed data
if (it.document.id == DriverOrders.docId){
adapter.notifyItemRemoved(it.oldIndex)
}
}
}
recyclerview_driverorders.adapter = adapter
}
class DriverOrders(val userUid: String, val userPhone: String,
val userName: String, val time: String,
val marketName: String, val amount: String, val storeimgUrl: String, val order: String,
val userImg: String):Item<GroupieViewHolder>() {
override fun getLayout(): Int {
return R.layout.driver_row
}
override fun bind(viewHolder: GroupieViewHolder, position: Int) {
viewHolder.itemView.driverorders_sName.text = marketName
viewHolder.itemView.driverorders_order.text = order
viewHolder.itemView.driverorders_time.text = Date
Picasso.get().load(storeimgUrl).fit().into(viewHolder.itemView.driverorders_sImg)
}
}

Json same name different data type Moshi Android

This is my model class and i have these types of json to convert in to this model. How i can do that with Moshi (Using Retrofit)
data class(var Id:Int, var image:List<String>)
{"Id":188, "image":"\/posts\/5fd9aa6961c6dd54129f51d1.jpeg"}
{"Id":188, "image":["\/posts\/5fd9aa6961c6dd54129f51d1.jpeg","\/posts\/5fd9aa6961c6dd54129f51d1.jpeg"]}
Your case is a bit unorthodox, in general I would avoid designing JSONs with matching field names but different signature. Anyway, the solution:
Define your model as follow:
data class MyModel(
#Json(name = "Id") val Id: Long,
#Json(name = "image") val images: List<String>
)
Then, you will have to create a custom adapter for it:
class MyModelAdapter {
#ToJson
fun toJson(model: MyModel): String {
// MyModel is data class so .toString() should convert it to correct Json format with
// image property as list of image path strings
return model.toString()
}
#FromJson
fun fromJson(reader: JsonReader): MyModel = with(reader) {
// We need to manually parse the json
var id: Long? = null
var singleImage: String? = null
val imageList = mutableListOf<String>()
beginObject()
while (hasNext()) {
// iterate through the JSON fields
when (nextName()) {
"Id" -> id = nextLong() // map the id field
"image" -> { // map the image field
when (peek()) {
JsonReader.Token.BEGIN_ARRAY -> {
// the case where image field is an array
beginArray()
while(hasNext()) {
val imageFromList = nextString()
imageList.add(imageFromList)
}
endArray()
}
JsonReader.Token.STRING -> {
// the case where image field is single string
singleImage = nextString()
}
else -> skipValue()
}
}
else -> skipValue()
}
}
endObject()
id ?: throw IllegalArgumentException("Id should not be null")
val images = if (singleImage != null) {
listOf(singleImage)
} else {
imageList
}
MyModel(Id = id, images = images)
}
}
Then, add the adapter to your moshi builder:
Moshi.Builder()
.add(MyModelAdapter())
.build()
That should do it. For complete code base, you can check my demo I just created that mirrors your case:
https://github.com/phamtdat/MoshiMultipleJsonDemo

How can I convert a list to string

data class Movie(
#SerializedName("movie_name")
val movieName : String
#SerializedName("genres")
val movieGenre : List<String>){}
How can I convert a list to string created every object in this data class
You can use additional property in Movie class to convert list to string, e.g. val genre:
data class Movie(
#SerializedName("movie_name")
val movieName: String,
#SerializedName("genres")
val movieGenre: List<String>
) {
val genre: String
get() = buildString { // builds new string using append() method on each item of movieGenre
movieGenre.forEach { append(it) }
}
}
Here is how to access it:
val movie: Movie = getMoviewFromInternet()
val movieGenre: String = movie.genre
That's achievable in Kotlin via joinToString(separator: String), like this:
data class Movie(
#SerializedName("movie_name")
val movieName : String,
#SerializedName("genres")
val movieGenre : List<String>
) {
val genre: String
// concatenate the items using the separator provided
get() = movieGenre.joinToString(" ")
}
You would use it in a main as follows
fun main() {
val genreList: List<String> = listOf(
"Horror", "Splatter", "Romance", "Comedy", "Mystery", "Adult"
)
val movieName = "A.R. Bitrary"
val movie = Movie(movieName, genreList)
println(movie.genre)
}
which then outputs
Horror Splatter Romance Comedy Mystery Adult

Categories

Resources