Firebase Realtime DB查询返回旧DataSnapshot 不重启无法获取新键问题
问题根因
Firebase Realtime Database 的 GetValueAsync() 方法默认优先读取本地缓存的快照数据。你使用带EndAt、LimitToLast的分页查询时,本地仅会缓存该次查询命中的范围数据,后续新增的条目不在之前缓存的查询范围内,因此重复调用GetValueAsync()读缓存时就拿不到新值。而你不加分页参数时查询的是全量数据,缓存会更新对应全量范围的快照,因此可以正常拿到新值。
之前给全路径引用开KeepSynced(true)会同步该路径下的所有数据到本地,数据量大时自然会卡顿。
可行解决方案
方案1:强制从服务端拉取查询结果
调用GetValueAsync时指定数据源为服务端,跳过本地缓存,每次直接拉取服务端最新的10条数据,不需要开启全量同步,也不会产生多余缓存:
FirebaseDatabase.DefaultInstance.GetReference("CarsForSale/") .OrderByKey() .EndAt(lastSavedKey) .LimitToLast(10) .GetValueAsync(DataSource.Server); // 新增DataSource参数强制走服务端
该方案适配大多数不需要离线使用分页查询的场景,实现成本最低。
方案2:给分页查询绑定实时监听
如果需要兼顾离线能力,同时要实时获取数据更新,不要给全路径引用加监听,直接给你构造好的分页查询对象绑定ValueChanged事件:
// 构造分页查询对象 var pageQuery = FirebaseDatabase.DefaultInstance.GetReference("CarsForSale/") .OrderByKey() .EndAt(lastSavedKey) .LimitToLast(10); // 绑定监听,仅同步该查询范围内的数据更新 pageQuery.ValueChanged += (sender, args) => { if (args.DatabaseError != null) { // 处理错误逻辑 return; } // 处理拿到的最新10条数据 var snapshot = args.Snapshot; }; // 不需要使用该查询时记得移除监听,避免内存泄漏 // pageQuery.ValueChanged -= 对应的委托方法
该方案仅同步当前分页查询范围内的数据,不会缓存全路径内容,不会造成卡顿,同时服务端该范围内的数据有更新时会自动推送到本地,无需手动调用拉取接口。
方案3:分页逻辑优化(可选)
如果你的场景是支持上拉加载更多+下拉刷新拿最新数据,下拉刷新时可以去掉EndAt参数,直接拉取最新的10条数据作为第一页,再更新本地记录的最新key,后续上拉加载时再用EndAt参数向后分页,也能避免缓存旧数据的问题。
内容的提问来源于stack exchange,提问作者SHAI
相关产品推荐
相关产品推荐

