如何将数据从 FCM 的 onMessageReceived() 发送到 Fragment?
Posted
技术标签:
【中文标题】如何将数据从 FCM 的 onMessageReceived() 发送到 Fragment?【英文标题】:How to send data from FCM's onMessageReceived() to Fragment? 【发布时间】:2020-04-21 04:22:35 【问题描述】:我正在使用 Firebase 云消息传递在我的应用中接收数据:
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)
当我收到 FCM 时,我想将它传递给我的 Fragment。我尝试使用 LiveData + ViewModel,但不幸的是,postValue()
实际上并没有从服务更改 ViewModel 中的数据,因为我无法从服务实例化对 ViewModel 的引用。
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
)
有没有更好的方法将数据从FirebaseMessagingService()
传递到我的片段,或者将数据发布到FirebaseMessagingService()
内的FcmViewModel()
?
【问题讨论】:
一个 hacky 解决方案是在Application
类中包含 livedata 对象,然后您的片段可以从那里订阅,您的服务也可以从那里发布。否则我会说将视图模型中的实时数据抽象到它自己的存储库类中,视图模型和服务都可以通过一些依赖注入来引用它
【参考方案1】:
LocalBroadcastManager
标记为已弃用,现在似乎没有标准的方法来执行此操作。
然而LiveData
与ViewModels
无关。您仍然可以使用LiveData
。我会推荐他评论过的@tyczj 的解决方案。或者您可以执行以下操作。
创建一个作为小型事件总线框架的单例类。这个单例类可以有你需要的LiveData
列表,Fragment
和Service
都可以访问 LiveData 的实例。 Service 和 Fragment 可以充当生命周期的所有者,因此您不会遇到任何问题。
下面是一个sudo代码
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")
)
您还可以创建自己的LiveData
子类,并通过覆盖onActive
和onInactive
函数来控制LiveData
中的数据更新
【讨论】:
谢谢,如果应用程序在前台,那就太好了。如果应用在后台,您知道如何在我的 Fragment 中接收 FCM 通知数据吗? (不点击通知) 我不确定 FCM 是否支持这一点。您必须单击通知才能访问捆绑数据。我必须检查最新的文档。 接受答案以上是关于如何将数据从 FCM 的 onMessageReceived() 发送到 Fragment?的主要内容,如果未能解决你的问题,请参考以下文章
我可以使用 FCM 云将数据从数据库发送到我的 Android 应用程序吗?
如何将数据从 java 服务类发送到 kotlin 活动类? [关闭]
如何使用 FCM 将通知从一台使用 Angular2 的计算机发送到另一台计算机