I ran into a rather strange problem. In my fragment there is a code for adding an item to the database through the child().setValue()
. In another fragment there is user authorization, where it checks if the user exists, it is also implemented using the onDataChange()
function.
Check user function [AuthFragment]:
private fun checkUserExist() {
val ref = FirebaseDatabase.getInstance().getReference("Users")
ref.child(auth.uid!!)
.addValueEventListener(object: ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()) {
// User exist
findNavController().navigate(R.id.action_authSecondStepFragment_to_authCompletedFragment)
} else {
// User not exist
saveUser()
}
}
override fun onCancelled(error: DatabaseError) {
throw error.toException()
}
})
}
Adding item to database function [AddingToDatabaseFragment]:
private fun addToFavorite() {
val hashMap = HashMap<String, Any>()
with(args) {
hashMap["id"] = getPlaceId()
hashMap["name"] = currentPlace.name
hashMap["location"] = currentPlace.description
hashMap["image"] = currentPlace.image
hashMap["description"] = currentPlace.description
}
val ref = FirebaseDatabase.getInstance().getReference("Users")
ref.child(getProfileUid()!!)
.child("Favorites")
.child(getPlaceId())
.setValue(hashMap)
.addOnSuccessListener {
Toast.makeText(requireContext(), "Succesfully added!", Toast.LENGTH_SHORT).show()
}
.addOnFailureListener {
Toast.makeText(requireContext(), "Error!", Toast.LENGTH_SHORT).show()
}
}
Actually, the problem is that when successfully authorizing through the onDataChange()
function, I get to another fragment, where I can already add some item to the database, and when adding (respectively, changing the database), the onDataChange()
function from of the PREVIOUS authorization fragment, in my case findNavController()
is called from a fragment that I am not even in, which causes the application to crash. How can I fix this problem?
CodePudding user response:
Since you use addValueEventListener
, you are registering a permanent listener. The only way to deactivate that listener is by detaching it, typically when it goes out of scope.
I usually try to put my attaching and detaching of listeners in the opposite life-cycle events of my activities. So if I attach in onStart
I'll detach in onStop
, and same for onUnpause
/onResume
.
For fragments you should follow the same logic, so onAttach
-> onDetach
, or onStart
-> onStop
, or onPause
-> onResume
.