I'm using Firebase Cloud Messaging to receive data in my app:
class CustomFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(msg: RemoteMessage?) {
val data = msg?.data ?: return
val name = data["name"] as String
val age = data["age"]?.toIntOrNull() ?: return
val bio = data["bio"] as String
val img1 = data["img1"] as String
val match = Profile(name, age, bio, img1, null, null)
Log.d(TAG, "onMessageReceived(): $name is $age")
val fcmViewModel = ViewModelProviders.of(this).get(FcmViewModel::class.java) // .of() only takes a fragment/activity
FcmViewModel().match.postValue(match)
Log.d(TAG, "Value: " + FcmViewModel().match.value.toString()) // null
super.onMessageReceived(msg)
}
When I receive the FCM, I want to pass it to my Fragment. I've tried to use LiveData + ViewModel, but unfortunately, postValue()
isn't actually changing the data in the ViewModel from the service because I can't instantiate a reference to the ViewModel from a service.
class FcmViewModel : ViewModel() {
val match: MutableLiveData<Profile> by lazy {
MutableLiveData<Profile>()
}
}
class MapFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
fcmViewModel.match.observe(this, Observer<Profile> { profile ->
log("${profile.name} is ${profile.age}") // doesn't print
})
}
}
Is there a better way to pass data from FirebaseMessagingService()
to my fragment or a way to post data to FcmViewModel()
within the FirebaseMessagingService()
?
With a LocalBroadcastManager
marked as deprecated, it' seems like there is no standard way of doing this now.
However LiveData
has nothing to do with ViewModels
. You can still use LiveData
. I would recommend @tyczj's solution which he has commented. Or you can do following.
Create a singleton class which will work as your small event bus framework. This singleton class can have list of LiveData
which you need and both Fragment
and Service
can access instance of LiveData. Service and Fragment can act as a lifecycle owner, so you will not face any problem.
Below is a sudo code
object Events {
val serviceEvent: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
}
class CustomFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(msg: RemoteMessage?) {
Events.serviceEvent.postValue(profileObj)
super.onMessageReceived(msg)
}
}
class MapFragment: Fragment {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Events.serviceEvent.observe(this, Observer<Profile> { profile ->
log("${profile.name} is ${profile.age}")
})
}
You can also create your own subclass of LiveData
and control the data updates in LiveData
by overriding onActive
and onInactive
functions
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With