Get data from a Firebase Realtime Database child - firebase

This my project I have 2 RecyclewView, the first selects the user I want to manipulate, which is working perfectly.
When selecting it I store your id and transfer it to a next screen that should show your medical history (using your id to search your database for your history).
But this recycler view remains blank, does not give an error but also does not return anything, maybe I'm missing the time to put the path to be taken to bring this history.
image BD Firestore: [1]: https://imgur.com/HOxQTsI
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_verificar_historico)
setSupportActionBar(toolbar_historico)
toolbar_historico.setTitle("Titulo Aqui")
userId = intent.extras?.getString("userId")
textViewX.setText(userId)
getLastKey()
val layoutManager = LinearLayoutManager(this)
recycler_view_historico.layoutManager = layoutManager
val dividerItemDecoration = DividerItemDecoration(recycler_view_historico.context, layoutManager.orientation)
recycler_view_historico.addItemDecoration(dividerItemDecoration)
adapter = HistoricoAdapter(this)
recycler_view_historico.adapter = adapter
getHistorico()
recycler_view_historico.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
total_item = layoutManager.itemCount
last_visible_item = layoutManager.findLastVisibleItemPosition()
if (isLoading && total_item <= last_visible_item + ITEM_COUNT) {
getHistorico()
isLoading = true
}
}
})
}
private fun getHistorico() {
if (!isMaxData) {
val query: Query
if (TextUtils.isEmpty(last_node))
query = FirebaseDatabase.getInstance().reference
.child("pacientes/$userId/historico")
.orderByKey()
.limitToFirst(ITEM_COUNT)
else
query = FirebaseDatabase.getInstance().reference
.child("pacientes/$userId/historico")
.orderByKey()
.startAt(last_node)
.limitToFirst(ITEM_COUNT)
query.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
if (p0.hasChildren()) {
val historicoLista = ArrayList<HistoricoRecycle>()
for (snapshot in p0.children)
historicoLista.add(snapshot.getValue(HistoricoRecycle::class.java)!!)
last_node = historicoLista[historicoLista.size - 1].data
if (!last_node.equals(last_key))
historicoLista.removeAt(historicoLista.size - 1)
else
last_node = "end"
adapter.addAll(historicoLista)
isLoading = false
} else {
isLoading = false
isMaxData = true
}
}
})
}
}
private fun getLastKey() {
val get_last_key = FirebaseDatabase.getInstance().getReference()
.child("pacientes/$userId/historico")
.orderByKey()
.limitToLast(1)
get_last_key.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
for (userSnapShot in p0.children)
last_key = userSnapShot.key
}
})
}

Related

updat listview in an activity after click update button in custom adapter

I have an activity (ProductList) contain listview to view all products in my database, and a custom adapter for the list (MyListAdapter) that contains update button when I click on it a dialoge open and update the product info.
I want that when I update the product info and close the dialog the listview updated in the same time.
ProductsList Activity
class ProductsList : AppCompatActivity() {
private lateinit var databaseHandler:DatabaseHandler
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_products_list)
databaseHandler = DatabaseHandler(this)
val product: ArrayList<Product> = databaseHandler.listProduct()
val productArrayId = Array(product.size){"0"}
val productArrayName = Array(product.size){"null"}
val productArrayQuantity = Array(product.size){"null"}
val allInfo = Array(product.size){"null"}
for((index, e) in product.withIndex()){
productArrayId[index] = e.getProductID().toString()
productArrayName[index] = e.getProductName()
productArrayQuantity[index] = e.getProductQuantity().toString()
allInfo[index] = e.getProductID().toString() + " " + e.getProductName() + " " + e.getProductQuantity().toString()
}
var myListAdapter = MyListAdapter(this,product)
lv_products.adapter = myListAdapter
}
}
MyListAdapter class
class MyListAdapter(private val context: Activity, private val products: ArrayList<Product>) : BaseAdapter() {
private var databaseHandler = DatabaseHandler(this.context)
override fun getCount(): Int {
return products.size
}
override fun getItem(position: Int): Any {
return products[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
#SuppressLint("ViewHolder")
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val inflater = LayoutInflater.from(context)
val customView = inflater.inflate(R.layout.custom_list, parent, false)
customView.tv_product_id.text = products[position].getProductID().toString()
customView.tv_product_name.text = products[position].getProductName()
customView.tv_product_quantity.text = products[position].getProductQuantity().toString()
customView.btn_edit_product.setOnClickListener {
val layout = LayoutInflater.from(context)
val view = layout.inflate(R.layout.update_dialog, null)
view.et_product_id.setText(products[position].getProductID().toString())
view.et_product_name.setText(products[position].getProductName())
view.et_product_quantity.setText(products[position].getProductQuantity().toString())
AlertDialog.Builder(context).setView(view).setTitle("update product info")
.setPositiveButton("yes") { _, _ ->
val status = databaseHandler.updateProduct(
view.et_product_id.text.toString().toInt(),
view.et_product_name.text.toString(),
view.et_product_quantity.text.toString().toInt()
)
if (status > -1) {
Toast.makeText(this.context, "record updated", Toast.LENGTH_LONG).show()
this.notifyDataSetChanged()
} else {
Toast.makeText(this.context, "update error", Toast.LENGTH_LONG).show()
}
}
.setNegativeButton("no") { _, _ -> }
.setIcon(R.drawable.ic_baseline_warning_24)
.show()
this.notifyDataSetChanged()
}
return customView
}
}

avoid fragment recreation BottomNavigationView

i want to avoid fragment recreation by using BottomNavigationView
i read about that FragmentTransaction.replace is the problem and changing to add would help, but that didn't work for me..
maybe you can see here where i'm wrong
this is my Host Activity which hosting 3 fragments with BottomNavigationView
'''
class Host : AppCompatActivity() {
var fragment: Fragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_host)
//for hide the actionBar (contains Fragment name) on top of the screen
val actionBar = supportActionBar
actionBar?.hide()
val navController = Navigation.findNavController(this, R.id.nav_host_fragment)
val navView = findViewById<BottomNavigationView>(R.id.nav_view)
navView?.setupWithNavController(navController)
NavigationUI.setupWithNavController(navView, navController)
mAdapter = NfcAdapter.getDefaultAdapter(this)
fragmentStayAlive()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
for (fragment in supportFragmentManager.fragments) {
fragment.onActivityResult(requestCode, resultCode, data)
}
}
fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) }
private fun fragmentStayAlive(){
val fragment1: Fragment = LobbyFragment()
val fragment2: Fragment = GameSessionFragment()
val fragment3: Fragment = UserStatusFragment()
val fm: FragmentManager = supportFragmentManager
var active = fragment1
fm.beginTransaction().add(R.id.nav_host_fragment, fragment3, "UserStatusFragment").hide(
fragment3
).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, fragment2, "GameSessionFragment").hide(
fragment2
).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, fragment1, "LobbyFragment").commit();
val mOnNavigationItemSelectedListener: BottomNavigationView.OnNavigationItemSelectedListener =
object : BottomNavigationView.OnNavigationItemSelectedListener {
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when (item.getItemId()) {
R.id.lobbyFragment -> {
fm.beginTransaction().hide(active).show(fragment1).commit()
active = fragment1
return true
}
R.id.gameSessionFragment -> {
fm.beginTransaction().hide(active).show(fragment2).commit()
active = fragment2
return true
}
R.id.userStatusFragment -> {
fm.beginTransaction().hide(active).show(fragment3).commit()
active = fragment3
return true
}
}
replaceFragment(active, null, true, true)
return false
}
}
}
fun replaceFragment(
fragment: Fragment,
#Nullable bundle: Bundle?,
popBackStack: Boolean,
findInStack: Boolean
) {
val fm = supportFragmentManager
val ft: FragmentTransaction = fm.beginTransaction()
val tag = fragment.javaClass.name
val parentFragment: Fragment?
parentFragment = if (findInStack && fm.findFragmentByTag(tag) != null) {
fm.findFragmentByTag(tag)
} else {
fragment
}
// if user passes the #bundle in not null, then can be added to the fragment
if (bundle != null) {
parentFragment!!.arguments = bundle
} else {
parentFragment!!.arguments = null
}
// this is for the very first fragment not to be added into the back stack.
if (popBackStack) {
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
} else {
ft.addToBackStack(parentFragment.javaClass.name + "")
}
ft.add(R.id.nav_view, parentFragment, tag)
ft.commit()
fm.executePendingTransactions()
}
'''
thanks for all the helpers!

How to query different references in firebase and check if one of the child is equal to the other childs value

I am not sure if the question seems perfect but I wIll appreciate any help
here is my firebase database
I have 2 different references.one is the user and the other is the item..its a buying and selling app..I want to set the users image to his item on the show item activity...
how do i go about the query..
if boyo#yahoo.com post an item,I want the other users to see his image and his full names under the showitemactivity
here is a screen showof my show activity item
thanks in anticipation
here is the code I am using
private fun getItemDetails(itemId: String?) {
val firebaseDatabase: FirebaseDatabase = FirebaseDatabase.getInstance()
var rootRef: DatabaseReference = firebaseDatabase.reference
rootRef.child("Items").child(itemId!!).addValueEventListener(object : ValueEventListener{
override fun onDataChange(p0: DataSnapshot) {
if (p0.exists()) {
val sellerid: String = p0.child("uid").value.toString()
(imagesArray as ArrayList<Items>).clear()
for (snapshot in p0.children) {
val items = p0.getValue(Items::class.java)
/* var decimalFormat: DecimalFormat = DecimalFormat("#,##0.00")
var formattedValue: String = decimalFormat.format(items!!.getpricee())*/
(imagesArray as ArrayList<Items>).add(items!!)
priceTV!!.text = items.getpricee()
titleTV!!.text = items.gettitlee()
descriptionTV!!.text = items.getdescriptionn()
categoryTV!!.text = items.getcategoryy()
subcategoryTV!!.text = items.getsubcategoryy()
state!!.text = items.getstatee()
lga!!.text = items.getlgaa()
date!!.text = items.getdatee()
time!!.text = items.gettimee()
rootRef.child("Users").addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
if(p0.exists()) {
for(snapshot in p0
.children) {
val users = snapshot.getValue(Users::class.java)
if(snapshot.equals(sellerid)) {
username!!.text = users!!.getFullnamee()
if(users.getImageee().isEmpty()) {
userImage!!.setImageResource(R.drawable.avatarplaceholder)
} else {
Picasso.get().load(users.getImageee())
.into(userImage)
}
}
}
}
}
})
}
}
sliderPageAdapter?.notifyDataSetChanged()
}
override fun onCancelled(p0: DatabaseError) {
}
})
}

i got this error and cant resolve it: Expected a List while deserializing, but got a class java.lang.String;

i kown that is sunday but i got this problem, and i dont have any idea about how i fix it.
ps: the other questions in stackoverflow are in java, im using kotlin, and are about map error, not list.
my class User
#Parcelize
class User (val primeiroLogin:Boolean, val tutorialComplete:Boolean, val
username:String, val uid:String, val viewed:ArrayList<String>) : Parcelable {
constructor() : this(true,false,"","", ArrayList())
}
most part of the activity where i got the error
var viewed = ArrayList<String>()
private fun selectCategories(){
val ref = FirebaseDatabase.getInstance().getReference("/users")
ref.addListenerForSingleValueEvent(object: ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
var cUid = ""
val user = FirebaseAuth.getInstance().currentUser
user?.let {
val uid = user.uid
cUid = uid
}
p0.children.forEach{
val user = it.getValue(User::class.java)
if(user?.uid == cUid){
viewed = user.viewed
}
}
}
})
}
private fun fetchCategories(){
val ref = FirebaseDatabase.getInstance().getReference("/categories")
ref.addListenerForSingleValueEvent(object: ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
val adapter = GroupAdapter<ViewHolder>()
p0.children.forEach{
val category = it.getValue(Category::class.java)
if(category != null){
for (i in 0..viewed.size) {
if(category.real_name != viewed[i]){
adapter.add(categories(category))
}
}
}
}
adapter.setOnItemClickListener { item, view ->
val categories = item as categories
val intent = Intent(view.context, LearningFirstLibras::class.java)
intent.putExtra(CATEGORY_KEY, categories.category)
startActivity(intent)
}
new_words_categories.adapter = adapter
}
})
.....
thank you guys!

Cannot fetch messages from another user FirebaseDatabase

This is a simple chat messaging app, using Firebase Realtime Database and the Authentication. I have successfully created the database, but I cannot fetch the message from one user to another. Because, when I send the message/click the send button, it creates different nodes, I think its a string node with quotation mark in the name. The node structure I created is user-messages --> fromId(current user uid) --> toUid(to whom the messages are sent).
To make more clear explanation, this is the screenshot of what happened.
I think the problem is, it creates a different nodes with the "uid", which means string. So the database has two nodes, one with the "...", and the other the normal one. For some info, I use some library such as Picasso image load, groupie, and parcelize.
This is the source code for the ChatLogActivity
import...
class ChatLogActivity : AppCompatActivity() {
companion object {
val TAG = "ChatLog"
}
val adapter = GroupAdapter<ViewHolder>()
var toUser: User? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat_log)
recyclerview_chat_log.adapter = adapter
toUser = intent.getParcelableExtra(NewMessageActivity.USER_KEY)
titleChatLog.text = toUser?.nama
listenForMessages()
arrowBack.setOnClickListener {
finish()
}
send_button_chat_log.setOnClickListener {
Log.d(TAG, "Attempt to send message.....")
performSendMessage()
}
}
private fun listenForMessages() {
val fromId = FirebaseAuth.getInstance().uid
val toId = toUser?.uid
val ref = FirebaseDatabase.getInstance().getReference("/user-messages/$fromId/$toId")
ref.addChildEventListener(object : ChildEventListener {
override fun onChildAdded(p0: DataSnapshot, p1: String?) {
val chatMessage = p0.getValue(ChatMessage::class.java)
if (chatMessage != null) {
Log.d(TAG, chatMessage.text)
if (chatMessage.fromId == FirebaseAuth.getInstance().uid) {
val currentUser = LatestMessageActivity.currentUser?: return
adapter.add(ChatFromItem(chatMessage.text, currentUser))
} else {
adapter.add(ChatToItem(chatMessage.text, toUser!!))
}
}
}
override fun onCancelled(p0: DatabaseError) {
}
override fun onChildChanged(p0: DataSnapshot, p1: String?) {
}
override fun onChildMoved(p0: DataSnapshot, p1: String?) {
}
override fun onChildRemoved(p0: DataSnapshot) {
}
})
}
private fun performSendMessage() {
val text = edittext_chat_log.text.toString()
val fromId = FirebaseAuth.getInstance().uid
val user = intent.getParcelableExtra<User>(NewMessageActivity.USER_KEY)
val toId = user.uid
val ref = FirebaseDatabase.getInstance().getReference("/user-messages/$fromId/$toId").push()
val toRef = FirebaseDatabase.getInstance().getReference("/user-messages/$toId/$fromId ").push()
if (fromId == null) return
val chatMessage = ChatMessage(ref.key!!, text, fromId, toId, System.currentTimeMillis() / 1000)
ref.setValue(chatMessage)
.addOnSuccessListener {
Log.d(TAG, "Save our chat message: ${ref.key}")
edittext_chat_log.text.clear()
recyclerview_chat_log.scrollToPosition(adapter.itemCount - 1)
}
toRef.setValue(chatMessage)
}
}
class ChatFromItem(val text: String, val user: User) : Item<ViewHolder>() {
override fun getLayout(): Int {
return R.layout.chat_from_row
}
override fun bind(viewHolder: ViewHolder, position: Int) {
val uri = user.profileImageUrl
val targetImageView = viewHolder.itemView.imageViewFrom
Picasso.get().load(uri).into(targetImageView)
viewHolder.itemView.textViewFrom.text = text
}
}
class ChatToItem(val text: String, val user: User) : Item<ViewHolder>() {
override fun getLayout(): Int {
return R.layout.chat_to_row
}
override fun bind(viewHolder: ViewHolder, position: Int) {
val uri = user.profileImageUrl
val targetImageView = viewHolder.itemView.imageViewTo
Picasso.get().load(uri).into(targetImageView)
viewHolder.itemView.textViewTo.text = text
}
}
And this is the ChatMessage, class that store the messages.
class ChatMessage(val id:String, val text: String, val fromId: String, val toId: String, val timeStamp: Long) {
constructor(): this("", "", "", "", -1)
}
I'm very glad if anyone can help this problem. Thank you

Resources