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

如何解决推送通知写入数据库仅保留最后一条的实时更新问题?

看起来你遇到的问题是每次Firebase推送过来,你把数据存在变量里,但没有立刻写入数据库,结果新推送覆盖了旧变量值,等你回到应用时只存了最后一条对吧?我来帮你梳理下怎么解决:

核心问题定位

你现在的逻辑是「接收推送→存变量→应用恢复时写入数据库」,但这个流程里变量是单次存储的,新推送会直接覆盖旧值,自然最后只保留最后一条。要实现数据库实时更新,关键是每次收到推送就立刻执行写入操作,而不是先存在变量里等后续处理。

具体修改步骤

针对你的Firebase Messaging Service代码,调整如下:

  1. 移除中间变量,收到推送直接写库
    把原本存变量的代码,替换成直接调用数据库插入方法。比如你的Service类里的OnMessageReceived方法:
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
    public override void OnMessageReceived(RemoteMessage message)
    {
        base.OnMessageReceived(message);
        
        // 1. 解析推送数据(根据你的payload结构调整)
        var pushData = new PushNotificationModel
        {
            MessageId = message.MessageId, // 用Firebase的唯一ID避免重复
            Title = message.GetNotification()?.Title ?? message.Data["title"],
            Body = message.GetNotification()?.Body ?? message.Data["body"],
            ReceivedTime = DateTime.Now,
            // 其他自定义字段...
        };
        
        // 2. 立刻写入数据库,而不是存在变量里
        _ = DatabaseHelper.InsertPushNotificationAsync(pushData);
        
        // 3. 如需展示通知,处理前台/后台的通知展示逻辑
        SendLocalNotification(pushData);
    }
}
  1. 把数据库操作放到后台线程
    数据库写入是IO操作,不能在Service的主线程执行,否则可能导致ANR或者性能问题。所以要把写库逻辑封装成异步方法:
// 数据库帮助类的异步插入方法
public static async Task InsertPushNotificationAsync(PushNotificationModel model)
{
    await Task.Run(() =>
    {
        using(var db = new SQLiteConnection(DbPath))
        {
            db.CreateTable<PushNotificationModel>();
            // 先检查是否已存在,避免重复写入
            var existing = db.Table<PushNotificationModel>()
                .FirstOrDefault(x => x.MessageId == model.MessageId);
            if(existing == null)
            {
                db.Insert(model);
            }
        }
    });
}
  1. 处理后台推送的特殊情况
    如果应用在后台,Firebase可能不会触发OnMessageReceived,而是直接展示系统通知。这种情况下,用户点击通知打开应用时,你需要从Intent里提取推送数据并写入数据库:
  • 在MainActivity的OnNewIntent方法里处理:
protected override void OnNewIntent(Intent intent)
{
    base.OnNewIntent(intent);
    if(intent.Extras != null)
    {
        var pushData = new PushNotificationModel
        {
            MessageId = intent.Extras.GetString("google.message_id"),
            Title = intent.Extras.GetString("title"),
            Body = intent.Extras.GetString("body"),
            ReceivedTime = DateTime.Now
        };
        _ = DatabaseHelper.InsertPushNotificationAsync(pushData);
    }
}
  • 同时,推送payload要包含data字段(而非仅notification),这样后台推送时数据才能传递到应用:
{
    "data": {
        "title": "新消息提醒",
        "body": "这是一条测试推送",
        "custom_key": "自定义值"
    },
    "to": "你的设备Token"
}
额外注意事项
  • 数据库实例管理:确保数据库路径在Service和Activity中都能正常访问,比如把路径设为全局常量,或者用依赖注入统一管理数据库实例。
  • 异常处理:可以给数据库操作加上try-catch,避免因写入失败导致Service崩溃:
public static async Task InsertPushNotificationAsync(PushNotificationModel model)
{
    try
    {
        await Task.Run(() =>
        {
            // 数据库写入逻辑
        });
    }
    catch(Exception ex)
    {
        // 记录日志或处理异常
        Console.WriteLine($"写入数据库失败: {ex.Message}");
    }
}

这样调整后,每次收到推送(不管前台还是后台)都会立刻把数据写入数据库,不会再出现只保留最后一条的情况,数据库也能实现实时更新啦!

内容的提问来源于stack exchange,提问作者Владимир

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:29:17