点击按钮持续更新Realtime Database同一对象仅首次生效如何解决
问题原因分析
- 本地缓存的
getTimerAdd变量未同步更新:你当前代码中的getTimerAdd应为页面初始化时从数据库拉取一次后存储在本地的变量,首次点击时用初始值减1写入数据库,之后没有监听数据库最新值更新本地的getTimerAdd,第二次点击时依然用最初的初始值减1,写入的数值和数据库现有值一致,所以不会触发更新。 - 未处理并发读写冲突:如果存在多端同时修改该数值的场景,直接调用
setValue很容易出现数值覆盖问题,计数增减类操作官方推荐使用事务处理实现。
解决方案
方案1:同步更新本地变量(快速修复)
仅适合单端操作的场景,每次写入数据库成功后同步更新本地变量即可:
uidRefItem.child("TimerAddOnemin").setValue(getTimerAdd - 1) .addOnSuccessListener(aVoid -> { // 写入成功后更新本地缓存的数值 getTimerAdd = getTimerAdd - 1; });
方案2:使用事务处理(推荐,兼容多端并发场景)
基于Firebase自带的原子事务能力,直接在数据库侧读取最新值计算,不需要依赖本地缓存的数值,可避免并发修改冲突:
uidRefItem.child("TimerAddOnemin").runTransaction(new Transaction.Handler() { @NonNull @Override public Transaction.Result doTransaction(@NonNull MutableData mutableData) { // 直接读取数据库当前最新值,不受本地缓存影响 Integer currentValue = mutableData.getValue(Integer.class); // 数值为空或已经为0时不执行扣减,可根据业务需求调整逻辑 if (currentValue == null || currentValue <= 0) { return Transaction.success(mutableData); } mutableData.setValue(currentValue - 1); return Transaction.success(mutableData); } @Override public void onComplete(@Nullable DatabaseError databaseError, boolean committed, @Nullable DataSnapshot dataSnapshot) { // 操作完成回调,可按需添加成功/失败提示 if (committed && dataSnapshot != null) { // 扣减成功后可选同步更新本地变量 getTimerAdd = dataSnapshot.getValue(Integer.class); } } });
注意事项
- 请确保数据库中
TimerAddOnemin字段为数字类型,不要存储为字符串格式,否则会出现取值为空导致扣减失败的问题。 - 请检查数据库对应路径的读写权限配置,避免权限不足导致后续写入失败。
内容的提问来源于stack exchange,提问作者Albert Pasco
相关产品推荐
相关产品推荐

