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

Xamarin Android前台FCM推送点击致SQLite数据丢失求助

问题诊断与解决方案

你的问题分为两个核心关联点:前台FCM通知跳转错误和SQLite数据丢失/无法读取,二者大概率是因为多进程启动冲突引发的连锁问题,以下分步骤逐一解决:


一、修复FCM前台通知跳转至SISActivity的问题

后台状态下系统会自动处理click_action参数,但前台接收FCM通知时,必须手动构建通知并指定跳转的PendingIntent,不能完全依赖默认参数逻辑。具体操作:

  1. 在你的FirebaseMessagingService子类中,重写OnMessageReceived方法,针对前台状态自定义通知跳转:
public override void OnMessageReceived(RemoteMessage message)
{
    base.OnMessageReceived(message);
    
    // 先判断应用是否处于前台(可以通过Activity生命周期回调实现状态跟踪)
    if (AppState.IsForeground)
    {
        var intent = new Intent(this, typeof(SISActivity));
        // 添加标志确保复用现有进程的Activity,避免启动新进程
        intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop | ActivityFlags.NewTask);
        var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Immutable);

        // 构建自定义通知
        var notificationBuilder = new NotificationCompat.Builder(this, "你的通知渠道ID")
            .SetContentTitle(message.GetNotification().Title)
            .SetContentText(message.GetNotification().Body)
            .SetSmallIcon(Resource.Drawable.ic_notification)
            .SetContentIntent(pendingIntent)
            .SetAutoCancel(true);

        var notificationManager = NotificationManager.FromContext(this);
        notificationManager.Notify(0, notificationBuilder.Build());
    }
    else
    {
        // 后台状态可沿用系统默认处理逻辑
        base.OnMessageReceived(message);
    }
}
  1. 修正SISActivity的IntentFilter配置,避免Action冲突:
// 建议加上包名前缀,防止与其他应用的Action重名
[IntentFilter(new[] { "com.yourpackage.SISActivity" }, Categories = new[] { Intent.CategoryDefault })]
public class SISActivity : AppCompatActivity 
{ 
    // 你的页面逻辑代码
}

注意:FCM通知里的click_action参数值要和上面的Action完全一致,比如com.yourpackage.SISActivity,不能只用简单的SISActivity。


二、解决SQLite数据丢失/无法读取的问题

数据丢失的核心原因是前台点击通知启动了新的应用进程,新进程中重复初始化数据库时引发了数据冲突或重置。解决方法:

  1. 确保SQLite连接单例化:你的GetConnection方法每次都创建新连接,多连接同时操作会导致数据锁或丢失,改为单例模式:
private static SQLiteAsyncConnection _instance;
private static readonly object _lockObj = new object();

public static SQLiteAsyncConnection GetConnection() 
{
    lock (_lockObj)
    {
        if (_instance == null)
        {
            try 
            {
                var sqlDbFileName = "edTheSIS.db3";
                var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                var path = System.IO.Path.Combine(documentsPath, sqlDbFileName);
                _instance = new SQLiteAsyncConnection(path);
            } 
            catch (Exception ex) 
            {
                Toast.MakeText(Application.Context, "Something went wrong", ToastLength.Short).Show();
                var objLog = new LogService();
                objLog.MobileLog(ex, SISConst.UserName);
            }
        }
        return _instance;
    }
}
  1. 避免表创建时的数据重置:CreateTableAsync如果遇到实体结构变更,可能会重建表导致数据丢失,明确指定只创建不存在的表:
// 添加CreateFlags.None确保仅当表不存在时才创建
await _conn.CreateTableAsync<LoggedInUser>(CreateFlags.None);

三、SQLite数据库恢复方法

如果数据已经丢失,可以尝试以下恢复途径:

  • 从设备文件系统提取备份:通过Android Studio的Device File Explorer,导航到/data/data/你的应用包名/files/edTheSIS.db3,如果开启了Android自动备份,可查看/data/data/你的应用包名/backup目录下的备份文件,替换当前数据库。
  • 应用内部备份恢复:如果你的应用有内部备份功能,直接从备份文件导入数据库。
  • 手动修复损坏的数据库:将当前数据库导出到电脑,用SQLite可视化工具(如SQLiteStudio)打开,检查是否有残留数据,修复后再导回设备。

内容的提问来源于stack exchange,提问作者Arvind Chourasiya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:13:26