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

iOS端Firebase Realtime Database离线计数功能异常求助

Flutter Firebase Realtime Database iOS离线计数重置问题

问题详情

开发基于Firebase Realtime Database的计数应用,已启用持久化并通过keepSynced(true)同步路径实现离线功能:

  • Android端离线状态下可正常展示历史计数,更新操作本地生效,联网后自动同步云端
  • iOS端离线时计数会重置为1,多次操作后数值仍保持1;联网后会拉取正确累计值(例如在线时计数为43,离线操作10次仍显示1,联网后变为53)

关联代码

Future<void> updateRealtimeData(String apiKey, String currentWeekKey) async {
  try {
    DatabaseReference _dbRef = FirebaseDatabase.instance.ref("stats");
    _dbRef.child("allTime/count").keepSynced(true);
    _dbRef.child("weeklyCounts/$currentWeekKey/count").keepSynced(true);

    final Map<String, dynamic> updates = {};
    updates['allTime/count'] = ServerValue.increment(1);
    updates['allTime/api_key'] = apiKey; 

    updates['weeklyCounts/$currentWeekKey/count'] = ServerValue.increment(1);
    updates['weeklyCounts/$currentWeekKey/api_key'] = apiKey;

    print('Update realtime data called');
    await _dbRef.update(updates);
    print('Stats updated successfully.');
  } catch (e) {
    print("Failed to update stats: $e");
  }
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  FirebaseDatabase.instance.setPersistenceEnabled(true);
  runApp(MyApp());
}

解决方案

1. 修正持久化初始化顺序

iOS平台要求必须在创建任何DatabaseReference之前启用持久化,否则会导致本地缓存无法正常工作。修改main函数:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  
  // 先配置持久化,再创建数据库引用
  final database = FirebaseDatabase.instance;
  database.setPersistenceEnabled(true);
  // 可选:调整缓存大小(默认10MB)
  database.setPersistenceCacheSizeBytes(100 * 1024 * 1024);
  
  runApp(MyApp());
}

2. 提前同步并等待缓存加载

在应用启动阶段主动同步目标路径,并等待本地缓存加载完成,避免离线时读取不到历史数据:

// 在首页的initState或应用初始化方法中调用
Future<void> initDatabaseSync(String currentWeekKey) async {
  DatabaseReference _dbRef = FirebaseDatabase.instance.ref("stats");
  // 仅初始化时同步一次,避免重复注册
  _dbRef.child("allTime/count").keepSynced(true);
  _dbRef.child("weeklyCounts/$currentWeekKey/count").keepSynced(true);
  
  // 等待本地缓存加载完成
  await _dbRef.child("allTime/count").once();
  await _dbRef.child("weeklyCounts/$currentWeekKey/count").once();
}

3. 移除重复的keepSynced调用

当前代码每次执行updateRealtimeData都会重复调用keepSynced(true),这会导致iOS端缓存监听异常。将同步逻辑移到初始化阶段,仅执行一次,删除updateRealtimeData中的keepSynced代码。

4. 优化本地读取逻辑

读取计数时优先从本地缓存获取,确保离线状态下能拿到正确的本地更新值:

Future<int> getCurrentAllTimeCount() async {
  final countRef = FirebaseDatabase.instance.ref("stats/allTime/count");
  final snapshot = await countRef.get();
  return snapshot.exists ? (snapshot.value as int) : 0;
}

5. 验证iOS配置

确认GoogleService-Info.plist中的DATABASE_URL正确指向你的Realtime Database实例,同时在Firebase控制台确认iOS应用已启用离线持久化(默认启用,但需检查)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:58:12