如何基于Firebase时间戳实现1小时后将PROMOTED布尔值设为false
Firebase场景下实现1小时后自动将PROMOTED置为false的落地方案
首先要先修正你现有代码的逻辑bug:
你当前代码里计算时间戳的逻辑完全错误——通过日期格式化截断取到的是当天零点的时间戳,根本不是用户触发激励广告的实际时刻,完全没法用来计算1小时的过期阈值。所有和SimpleDateFormat相关的冗余代码都可以删掉,直接获取当前毫秒级时间戳即可。
修正后的写入逻辑参考:
if (mRewardedAd != null) { Activity activityContext = getActivity(); mRewardedAd.show(activityContext, new OnUserEarnedRewardListener() { @Override public void onUserEarnedReward(@NonNull RewardItem rewardItem) { Log.d("TAG", "The user earned the reward."); btn_free_promo.setVisibility(View.GONE); // 直接取当前毫秒级时间戳,替换原来所有日期格式化的冗余代码 long timestamp = System.currentTimeMillis(); Map<String, Object> mixData = new HashMap<>(); mixData.put("timestamp", timestamp); mixData.put("PROMOTED", true); reference.child("MIXES").child(title).setValue(mixData); } }); }
核心实现注意事项
绝对不要依赖客户端本地的延迟任务(比如Handler.postDelayed)来做1小时后的状态更新,这种方案完全不可靠:
- 用户一旦杀掉APP进程,延迟任务会被系统直接回收,永远不会触发
- 安卓各品牌系统的后台杀进程机制激进,根本无法保证APP能在后台存活满1小时
- 用户随意修改系统时间,会直接打乱定时触发的时间节点
两种可靠的实现路径
- 方案一:云端定时任务批量更新(无客户端依赖)
部署Firebase云端定时函数,按照固定周期(比如每10-15分钟执行一次)扫描数据库中满足两个条件的条目:PROMOTED字段值为true、当前时间减去存储的timestamp值超过3600000毫秒(即1小时的毫秒数),扫描到的条目直接批量把PROMOTED字段更新为false即可。这种方案完全不受客户端运行状态影响,无论用户有没有打开APP,到时间都会自动完成状态更新。 - 方案二:查询时实时做过期判断(零服务端成本)
如果不想维护云端函数,完全可以不用手动触发PROMOTED=false的更新操作。在读取MIXES节点、展示对应UI的逻辑里加一层判断:计算当前时间和存储的
timestamp的差值,如果差值超过3600000毫秒,不管数据库里存的PROMOTED是什么值,直接按照PROMOTED=false的逻辑处理展示。
这种方案从根源上避免了漏更新、定时任务失效的问题,甚至连额外的写库操作都可以省掉——只要有存储的时间戳,随时可以算出当前账号是不是还在推广有效期内。
内容的提问来源于stack exchange,提问作者markharrop
相关产品推荐
相关产品推荐

