You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用后台状态下无法将推送通知数据保存至Room数据库

解决FCM后台/非活跃状态下无法保存通知至Room的问题

问题核心原因

你的FCM Payload同时包含notification和data字段:

  • 应用前台时,FirebaseMessagingService的onMessageReceived会被触发,能正常拿到所有数据并启动WorkManager保存。
  • 应用后台/非活跃时,系统会自动接管notification字段展示通知,不会触发onMessageReceived,只有用户点击通知时,数据才会通过启动的Activity传递,这时候才有可能处理保存逻辑。

解决方案

方案1:后端调整Payload(推荐)

让后端只发送纯data消息,移除notification字段。这样无论应用处于前台还是后台,onMessageReceived都会被触发,你可以在该方法内正常启动SaveNotificationWorker保存数据。

调整后的示例Payload:

{
    "data": {
        "title": "কথা চলুক সেরা অফারে!",
        "body": "১৯৯ টাকায় ৩০০ মিনিট ৩০ দিন মেয়াদে পেতে ট্যাপ করুন!",
        "imageUrl": "https://myapp-dev-static.robi.com.bd/images/payment/bkash.png",
        "description": "১৯৯ টাকায় ৩০০ মিনিট ৩০ দিন মেয়াদে পেতে ট্যাপ করুন!",
        "sentAt": "1731929876",
        "expiredAt": "1731982676",
        "buttonText": "Open Recharge",
        "type": "in_app",
        "url": "myapp-ppd://dashboard",
        "image": "https://media.giphy.com/media/Ju7l5y9osyymQ/giphy.gif",
        "token": "XXX"
    },
    "operator": "moon"
}

之后在RasaFcmService的onMessageReceived中,自行解析data字段构建通知展示,同时启动SaveNotificationWorker保存数据。

方案2:客户端适配现有Payload(后端无法修改时)

如果后端不能调整Payload,需要处理用户点击通知的场景:

  1. 在AndroidManifest中配置接收通知点击的Activity,确保其launchMode设置为singleTop或合适的模式:
<activity
    android:name=".ui.NotificationClickActivity"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
  1. 在该Activity的onCreate或onNewIntent中,解析Intent携带的FCM数据,启动SaveNotificationWorker:
class NotificationClickActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        handleNotificationData(intent)
        finish()
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.let { handleNotificationData(it) }
    }

    private fun handleNotificationData(intent: Intent) {
        val data = intent.extras ?: return
        val notificationData = parseNotificationData(data)
        val workRequest = OneTimeWorkRequestBuilder<SaveNotificationWorker>()
            .setInputData(workDataOf("notification_data" to Gson().toJson(notificationData)))
            .build()
        WorkManager.getInstance(this).enqueue(workRequest)
    }
}
  1. 确保SaveNotificationWorker能正确解析输入的数据并写入Room。

方案3:检查WorkManager后台执行约束

确认SaveNotificationWorker的执行约束是否过于严格,比如不必要的网络约束导致后台无法执行:

// 错误示例:如果保存Room不需要网络,不要加这个约束
.setRequiredNetworkType(NetworkType.CONNECTED)

// 正确示例:仅保留必要约束(如不需要网络则移除)
val workRequest = OneTimeWorkRequestBuilder<SaveNotificationWorker>()
    .build()

测试验证

使用adb命令模拟发送FCM消息,测试后台状态下的保存逻辑:

adb shell am broadcast -a com.google.firebase.MESSAGING_EVENT -n 你的包名/com.google.firebase.messaging.FirebaseMessagingReceiver --es "data" "{\"title\":\"测试标题\",\"body\":\"测试内容\"}"

内容的提问来源于stack exchange,提问作者Aminul Haque Aome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:17:18