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

Realm .NET SDK离线功能异常及首次离线无法使用问题求助

问题分析与解决方案

核心问题根源

  1. 首次离线启动失败:InitRealms方法直接调用LogInAsync,离线时登录失败导致config未初始化,后续Realm.GetInstance(config)传入null引发空引用异常。
  2. 离线订阅逻辑缺陷:离线状态下调用WaitForSynchronizationAsync会因无网络失败,且原代码吞掉所有异常,无法定位问题。

具体解决方案

1. 优先使用本地缓存用户,实现离线启动支持

Realm Sync会自动缓存已登录用户,无需每次联网登录。修改InitRealms方法,先尝试读取本地缓存用户,失败再尝试登录:

public async static Task InitRealms()
{
    try
    {
        var myRealmAppId = "application-2-dfsre";
        var app = Realms.Sync.App.Create(myRealmAppId);
        
        // 优先获取本地缓存的已登录用户
        var user = app.CurrentUser;
        if (user == null || !user.IsLoggedIn)
        {
            try
            {
                // 缓存无用户时,尝试联网登录
                user = await app.LogInAsync(Credentials.EmailPassword("arup@gmail.com", "aruparup"));
            }
            catch (Exception loginEx)
            {
                // 离线登录失败时,再次检查缓存(可能存在过期但仍可离线使用的用户)
                user = app.CurrentUser;
                if (user == null)
                {
                    // 完全首次使用必须联网初始化,抛出明确异常
                    throw new InvalidOperationException("首次使用请联网完成初始化");
                }
            }
        }

        // 配置Flexible Sync,适配离线场景
        config = new FlexibleSyncConfiguration(user)
        {
            EnableSessionMultiplexing = true,
            SyncTimeout = TimeSpan.FromSeconds(5) // 缩短离线同步超时时间
        };
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Realm初始化错误: {ex.Message}");
        throw; // 不要吞掉异常,让上层处理
    }
}

2. 修改订阅逻辑,兼容离线状态

离线时订阅更新可在本地完成,同步操作失败时无需中断流程,直接使用本地数据:

public async static Task SubscribeProducts()
{
    try
    {
        if (App.config == null)
        {
            throw new InvalidOperationException("请先完成Realm初始化");
        }

        App.realmProducts = Realm.GetInstance(App.config);

        // 本地更新订阅,离线也能执行
        await App.realmProducts.Subscriptions.UpdateAsync(() =>
        {
            var products = App.realmProducts.All<Products>();
            // 添加updateExisting避免重复订阅报错
            App.realmProducts.Subscriptions.Add(products, updateExisting: true);
        });

        try
        {
            // 尝试同步订阅,离线时捕获异常忽略即可
            await App.realmProducts.Subscriptions.WaitForSynchronizationAsync();
        }
        catch (Exception syncEx)
        {
            Console.WriteLine("订阅同步失败(当前离线): " + syncEx.Message);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("产品订阅错误: " + ex.Message);
        throw;
    }
}

3. 关键优化点

  • 替换async void为async Task:异步方法返回Task才能正确捕获异常,避免静默崩溃。
  • 移除空catch块:空catch会隐藏错误,至少记录日志或抛出明确异常。
  • 首次使用必须联网:Flexible Sync需要首次登录获取用户凭证与初始元数据,之后才能离线使用;若需完全无网络的本地数据库,应使用非同步版Realm。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:30:28