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

Xamarin中如何借助FirebaseDatabase.net实现Firebase Realtime离线同步

实现方案

1 开启Firebase内置离线持久化

Firebase Realtime Database 本身自带离线缓存能力,开启后写入、读取操作在离线时会自动操作本地缓存,网络恢复后自动同步本地变更到云端,是成本最低的实现方案。
修改你的FirebaseService初始化代码,开启离线支持:

public class FirebaseService    
{
    FirebaseClient firebase;
    public FirebaseService()
    {
        firebase = new FirebaseClient("https://xxxxxxx-xxxx-xxxx.firebaseio.com/",
            new FirebaseOptions
            {
                // 开启离线持久化,所有读写操作会优先走本地缓存,网络恢复自动同步
                OfflineDatabaseEnabled = true
            });
    }
}

开启后你原有大部分代码不需要修改,就可以获得基础的离线能力:

  • 离线时写入操作会存在本地缓存,联网后Firebase会自动同步到云端,不需要手动处理
  • 离线时查询操作会返回本地缓存的已有数据

2 补充更稳定的待同步队列(可选,适合对数据可靠性要求高的场景)

如果担心Firebase内置缓存丢数据,可以额外加一层本地待同步队列,用SQLite或者Xamarin.Essentials的Preferences、SecureStorage存储待同步的Contato数据,步骤如下:

  • 写入数据时先判断网络状态,在线直接调用PostAsync,离线就把数据存入本地待同步队列
  • 注册网络状态变化监听,网络从离线变为在线时,遍历本地待同步队列,依次上传到云端,上传成功后删除本地队列里的对应数据

修改后的完整代码示例

using SQLite; // 需要安装sqlite-net-pcl包
using Xamarin.Essentials;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Firebase.Database;
using Firebase.Database.Query;

public class FirebaseService    
{
    private readonly FirebaseClient firebase;
    private readonly SQLiteAsyncConnection _db;

    public FirebaseService()
    {
        // 初始化Firebase,开启离线缓存
        firebase = new FirebaseClient("https://xxxxxxx-xxxx-xxxx.firebaseio.com/",
            new FirebaseOptions
            {
                OfflineDatabaseEnabled = true
            });

        // 初始化本地SQLite存待同步数据
        var dbPath = Path.Combine(FileSystem.AppDataDirectory, "SyncQueue.db3");
        _db = new SQLiteAsyncConnection(dbPath);
        _db.CreateTableAsync<PendingContato>().Wait();

        // 监听网络状态变化,恢复联网时触发同步
        Connectivity.ConnectivityChanged += async (s, e) =>
        {
            if (e.NetworkAccess == NetworkAccess.Internet)
            {
                await SyncPendingData();
            }
        };
    }

    // 待同步数据模型
    public class PendingContato : Contato
    {
        [PrimaryKey, AutoIncrement]
        public int SyncId { get; set; }
    }

    public async Task AddContato(int id, string nome, string email)
    {
        var contato = new Contato() { Id = id, Nome = nome, Email = email };
        if (Connectivity.NetworkAccess == NetworkAccess.Internet)
        {
            // 在线直接上传
            await firebase.Child("Contatos").PostAsync(contato);
        }
        else
        {
            // 离线存入本地待同步队列
            await _db.InsertAsync(new PendingContato { Id = id, Nome = nome, Email = email });
        }
    }

    public async Task<List<Contato>> GetContatos()
    {
        // 先拿云端/离线缓存的数据
        var cloudData = (await firebase.Child("Contatos").OnceAsync<Contato>())
            .Select(item => item.Object)
            .ToList();
        // 再合并本地待同步的数据,避免用户看不到自己刚离线提交的数据
        var pendingData = await _db.Table<PendingContato>().ToListAsync();
        cloudData.AddRange(pendingData);
        return cloudData;
    }

    // 同步本地待队列数据
    private async Task SyncPendingData()
    {
        var pendingList = await _db.Table<PendingContato>().ToListAsync();
        foreach (var item in pendingList)
        {
            try
            {
                await firebase.Child("Contatos").PostAsync(new Contato { Id = item.Id, Nome = item.Nome, Email = item.Email });
                // 上传成功删除本地记录
                await _db.DeleteAsync(item);
            }
            catch
            {
                // 上传失败保留,下次再试
                continue;
            }
        }
    }
}

// 你的原有Contato模型
public class Contato
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public string Email { get; set; }
}

注意事项

  • Firebase内置离线缓存的存储上限是10MB,如果你的数据量很大,建议用自定义待同步队列的方案
  • 每次App启动时可以主动调用一次SyncPendingData(),避免App启动时已联网、没有触发网络状态变化导致的待同步数据积压
  • 使用Xamarin.Essentials的Connectivity需要在Android项目中添加ACCESS_NETWORK_STATE权限,iOS无需额外配置
  • 如果不需要极高的数据可靠性,仅开启第一步的OfflineDatabaseEnabled即可满足需求,无需额外开发队列逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:06:04