I am implementing the MVVM in fragments using the bottom navigation with firebase. But it's not working in my case. I searched for many solutions but didn't solve my problem.
I implemented viewModel in the fragment and apply observer to it. In the ViewModel class, call the method(getting data from firebase) with return type LiveData from the repository.
I'm using these dependencies
dependencies
// Fragment Navigation using JetPack
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
Repository.kt
// Get emergency requests
fun getEmergencyRequests(): LiveData<MutableList<EmergencyRequests>> {
val mutableData = MutableLiveData<MutableList<EmergencyRequests>>()
val requestListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
if (dataSnapshot.exists() && dataSnapshot.hasChildren()) {
// Get Post object and use the values to update the UI
val listData = mutableListOf<EmergencyRequests>()
for (snapshot in dataSnapshot.children) {
val model = snapshot.getValue(EmergencyRequests::class.java)
model?.let {
model.requestId = snapshot.ref.key.toString()
listData.add(it)
}
}
listData.sortByDescending { it.timestamp }
mutableData.value = listData
}
}
override fun onCancelled(error: DatabaseError) {
Log.e("EMERGENCIES_FAIL", error.message)
}
}
emergencyRequestRef?.addValueEventListener(requestListener)
return mutableData
}
ViewModel.kt
private val repository: HomeRepository = HomeRepository()
fun getRequests(): LiveData<MutableList<EmergencyRequests>> {
repository.getEmergencyRequests()
val mutableData = MutableLiveData<MutableList<EmergencyRequests>>()
repository.getEmergencyRequests().observeForever {
mutableData.value = it
}
return mutableData
}
Fragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Initialize
initialization()
// Recyclerview
binding.recyclerView.layoutManager = LinearLayoutManager(mContext)
adapter = EmergenciesAdapter(mContext, object : OnRequestClick {
override fun onClick(model: EmergencyRequests) {
}
})
binding.recyclerView.adapter = adapter
// Get emergencies
// getEmergencies()
viewModel = ViewModelProvider(mContext).get(HomeViewModel::class.java)
observer()
}
private fun observer() {
viewModel.getRequests().observe(viewLifecycleOwner, {
adapter.setDataList(it)
adapter.notifyDataSetChanged()
})
}
Not sure if this will fix it for you, but if you are using bottom navigation view
and want fragments
to maintain a backstack
for the visited destinations, then with this version of Navigation dependency
you can get to save the backstacks
automatically, use these Navigation dependencies
:
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.0-alpha01'
implementation 'androidx.navigation:navigation-ui-ktx:2.4.0-alpha01'
UPDATE
In your repository, are you able to get the data back? since the function might be returning before it gets data from firebase. I would suggest refactoring it a bit like this:
Repository.kt
private val _data: MutableLiveData<MutableList<EmergencyRequests>> = MutableLiveData()
val data: LiveData<MutableList<EmergencyRequests>> get() = _data
// Get emergency requests
fun getEmergencyRequests() {
val requestListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
if (dataSnapshot.exists() && dataSnapshot.hasChildren()) {
// Get Post object and use the values to update the UI
val listData = mutableListOf<EmergencyRequests>()
for (snapshot in dataSnapshot.children) {
val model = snapshot.getValue(EmergencyRequests::class.java)
model?.let {
model.requestId = snapshot.ref.key.toString()
listData.add(it)
}
}
listData.sortByDescending { it.timestamp }
_data.value = listData
}
}
override fun onCancelled(error: DatabaseError) {
Log.e("EMERGENCIES_FAIL", error.message)
}
}
emergencyRequestRef?.addValueEventListener(requestListener)
}
ViewModel.kt
private val repository: HomeRepository = HomeRepository()
fun getRequests(): LiveData<MutableList<EmergencyRequests>> {
repository.getEmergencyRequests()
return repository.data
}